使用python接收高速率的UDP数据包

2024-04-29 08:15:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用python从FPGA接收UDP数据包流,试图尽可能少地丢失数据包。 数据包速率从5kHz到一些MHz,我们希望在特定的时间窗口(代码中的acq_时间)中获取数据。 我们现在有了这个代码:

BUFSIZE=4096
dataSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
dataSock.settimeout(0.1)
dataSock.bind((self.HOST_IP, self.HOST_PORT))
time0=time.time()
data_list = []
while time.time()-time0<acq_time:
     fast_acquisition(data_list)

def fast_acquisition(data_list_tmp):
    data, addr = dataSock.recvfrom(self.BUFSIZE)
    data_list_tmp.append(data) 
    return len(data)

在采集之后,我们把数据表保存在磁盘上。在

这个代码应该尽可能的简单和快速,但是它仍然太慢,即使在5kHz的频率下我们也会丢失太多的数据包,我们认为这是因为当我们读取并在列表中存储一个数据包并检查时间时,下一个(或多个)到达并丢失。 有没有办法让插座保持打开?我们是否可以用并行处理“串联”打开多个套接字,以便在保存第一个套接字的文件时,第二个套接字可以接收另一个数据包? 我们甚至可以考虑使用另一种语言来接收和存储磁盘上的数据包。在


Tags: 代码selfhostdatatime时间socket数据包
2条回答

UDP数据包丢失的原因有很多,当然,将它们从套接字队列中取出并存储它们的速度无疑是一个因素,至少最终是这样。然而,即使你有一个专门的C语言程序来处理它们,如果你期望每秒接收到超过一百万个UDP包,你也不太可能接收到所有的UDP包。在

我要做的第一件事是确定python性能是否是您的瓶颈。根据我的经验,更可能的是,首先,您只是在耗尽接收缓冲区空间。内核将在套接字的接收队列中存储UDP数据报,直到空间耗尽。您也许可以用一个C程序稍微扩展一下这个容量,但是如果数据包以足够高的速度传入,那么您仍然会比耗尽套接字更快地耗尽空间。在

假设您在linux上运行,那么看看这个答案,了解如何配置套接字的接收缓冲区空间,并检查系统范围内的最大值,该值也是可配置的,可能需要增加。 https://stackoverflow.com/a/30992928/1076479

(如果你不在linux上,我真的不能给出任何具体的指导,尽管同样的因素也可能适用。)

有可能您将无法足够快地接收数据包,即使有更多的缓冲区空间,甚至在C程序中。在这种情况下,@game0ver使用tcpdump的想法可能会更好,如果你只需要承受一个短暂的密集的数据包突发,因为它使用一个低层次的接口来获取数据包(并且是高度优化的)。但是,当然,你不仅要有UDP有效载荷,而且还要有完整的原始数据包,在处理它们之前,还需要剥离IP和以太网层的报头。在

您可以使用^{},它在C中实现)来捕获UDP流量,因为它比^{}快:

#!/bin/bash

iface=$1 # interface, 1st arg
port=$2  # port, 2nd arg

tcpdump -i $iface -G acq_time_in_seconds -n udp port $port -w traffic.pcap

然后您可以使用例如^{}来处理该流量

^{pr2}$

相关问题 更多 >