Wysyłam 32 bajtów pakietów co 1 ms do tego gniazda. Chcę wydrukować dane po każdej 40 ms. I najwyraźniej kod to robi. Ale nawet gdy przestanę wysyłać dane, nadal nadal widzę, że dane są drukowane. Czy utrzymuje dane w niektórych pamięci podręcznej? lub po prostu gniazdo Pythona ma ogromne opóźnienie? Dlaczego?

Kod wygląda następująco:

## Import necessary libraries
import math
import numpy as np
import socket
import struct
import time
from synchrophasor.frame import CommandFrame
from datetime import datetime


## Configure socket for Phasor data ##

UDP_IP = "10.10.114.22"
UDP_PORT = 8208 #UDP phasor values 32 bytes (V,phi,P)
sock_ph = socket.socket(socket.AF_INET,  # Internet
                     socket.SOCK_DGRAM)  # UDP
sock_ph.bind((UDP_IP, UDP_PORT))
print("socket bound, waiting for data...")


while True:

    raw = sock_ph.recv(32)
    #print(raw)
    mag = struct.unpack('d', raw[8:16])[0]
    # print("mag =",mag,type(mag))
    angle = struct.unpack('d', raw[16:24])[0]
    # print("angle =",angle,type(angle))
    header = struct.unpack('d', raw[0:8])[0]
    # print("header =",header,type(header))
    phasor = (mag, angle)
  
    Vol_A=raw
    VA = float(mag)
    phi_A = float(angle)
    VB = VA
    phi_B = phi_A+(math.pi) * 2 / 3
    VC = VA
    phi_C = phi_A-(math.pi) * 2 / 3
    time.sleep(1/25)
    # pmu.send_data(phasors=[(VA,phi_A),(VB,phi_B),(VC,phi_C)],analog=[9.91],digital=[0x0001])
    #time.sleep(1/config_rr)
    print([(VA,phi_A),(VB,phi_B),(VC,phi_C),datetime.now()])
0
Rambo partyush 22 lipiec 2020, 11:05

1 odpowiedź

Najlepsza odpowiedź

Większość programów nie chce odrzucić nieprzeczytanych datagramów, więc większość OSS będzie im buforować je dla Ciebie. Twoja sprawa jest nieco niezwykła, więc trzeba będzie pisać kod, aby obsłużyć ten przypadek. Zmieniłbym swój kod, aby zrobić coś w rodzaju:

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('', 8208))

# block until we read an initial packet
raw = s.recv(1024)
s.setblocking(False)

while True:
    # unpack
    header, mag, angle = struct.unpack('ddd', raw)

    # do something with data
    print(f'header={header} mag={mag} angle={angle}')

    # sleep for some time
    time.sleep(1/25)

    # discard any packets you've received in the mean time
    while True:
        try:
            raw = s.recv(1024)
        except OSError as err:
            # OS buffer is empty: we've therefore got the most recent data
            if err.errno == socket.EWOULDBLOCK:
                break
            # something else failing, reraise the error
            raise

Zauważ, że sugestia Steffen Ullrich wysyłania danych na właściwej szybkości byłaby łatwiejsza, ale zakłada, że masz kontrolę nad procesem wysyłania. Fakt, że powiedziałeś "ja wysyłam" sugeruje, że zrobisz, a więc prawdopodobnie zrobiłbym lepsze rozwiązanie

1
Sam Mason 22 lipiec 2020, 10:05