Python UDP接收器高包率下超时但Wireshark可接收,求解决方案
高包率UDP端口无法用Python socket接收数据的问题
我尝试用Python编写一个简单的UDP接收器,读取数据采集设备发送的连续数据流。设备已配置为通过UDP向192.168.0.10的4000和4001端口发送两路数据流,其中4001端口的数据包发送速率更高。笔记本以太网接口已设置为该静态IP以接收数据。
4000端口的低速数据流可正常接收,但用相同代码监听4001端口时,会触发超时异常。我原本以为高包率UDP的最大问题是缓冲区溢出丢包(这在我的场景中可接受),但socket.recv(1024)触发超时意味着缓冲区无数据?而Wireshark明明能捕获到数据,这让我无法理解。
测试代码示例:
import socket for i in range(3): # 尝试多次 try: socket_i = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) socket_i.settimeout(5) socket_i.bind(('192.168.0.10', 4001)) #4000正常,4001不行 raw = socket_i.recv(1024) socket_i.close() print(raw) except Exception as ex: # 监听4001时触发异常:超时 socket_i.close() print('failed') print(ex)
[Wireshark截图:仅显示4001端口的数据包,因该流速率较高]
我查阅过类似问题,结论是Python存在性能瓶颈,但其他人仍能接收数据,而我完全无法接收,仅触发超时。我认为我的包率并非极高,不知是否有误?
我尝试按照建议增大接收缓冲区:
socket_i.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1024*1024*1024)
尝试了多种缓冲区大小均无效,增大超时时间也无济于事。
最后我尝试使用socketserver包编写UDP服务器:
import socketserver class MyUDPHandler(socketserver.BaseRequestHandler): """ 该类的工作方式类似于TCP处理类,不同之处在于 self.request由数据和客户端套接字组成,由于没有连接, 发送数据回客户端时必须显式指定客户端地址。 """ def handle(self): data = self.request[0].strip() socket = self.request[1] print("{} wrote:".format(self.client_address[0])) print(data) # socket.sendto(data.upper(), self.client_address) # 不需要回传数据 if __name__ == "__main__": with socketserver.UDPServer(('192.168.0.10', 4001), MyUDPHandler) as server: server.serve_forever()
监听4000端口时行为正常,但监听4001端口时代码无响应(可能默认超时时间过长)。我猜测socketserver包是基于socket包实现的?
我希望能得到帮助!
更新:
我通过pyshark编写UDP接收器临时解决了问题,但这种方法比较粗糙,我并不满意。想到既然Wireshark能接收数据,pyshark或许可行。仍希望得到基于socket包的解决方案!
临时解决方案代码:
import pyshark ip = '192.168.0.10' port = 4001 capture = pyshark.LiveCapture(bpf_filter=f'dst host {ip} and dst port {port}', use_json=True, include_raw=True) for pkt in capture.sniff_continuously(): raw = bytearray.fromhex(pkt.udp.payload_raw[0]) print(raw)
内容的提问来源于stack exchange,提问作者Robbert-Jan
相关产品推荐
相关产品推荐

