Python UDP套接字;源停止时仍在接收数据;为什么?

Python UDP socket; still receiving data when source is stopped; why?

我每 1 毫秒向这个套接字发送 32 个字节的数据包。我希望每 40 毫秒打印一次数据。显然代码就是这样做的。但即使我停止发送数据,我仍然继续看到正在打印数据。 它是否将数据保存在某个缓存中?或者只是 python 套接字有很大的延迟?为什么?

代码如下:

## 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()])

大多数程序不想丢弃未读数据报,因此大多数操作系统会为您缓冲它们。您的情况有些不寻常,因此您需要编写代码来处理这种情况。我会更改您的代码以执行以下操作:

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

请注意,Steffen Ullrich 以正确的速率发送数据的建议会更容易,但前提是您可以控制发送过程。你说“我正在发送”这一事实表明你这样做了,因此可能会做出更好的解决方案