Sockets 如何在vc+中连续接收大量UDP数据包+;

Sockets 如何在vc+中连续接收大量UDP数据包+;,sockets,udp,Sockets,Udp,我正在编写一个GUI应用程序,它连续地从4Gb数据的FPGA板接收UDP数据包(应用程序是一个数据检索系统) 我创建了自己的类,继承自CAyncSocket,在接收消息时,我通过ReceiveFromAPI读取数据包,并将数据写入文件 由于数据包是从FPGA连续发送的(大约400k个1KB数据包),我的应用程序丢失了这些数据包。我只收到20万包。但当我用Wireshark监控时,所有数据包都被接收到 有谁能提出任何技术或算法来解决这个问题,这样我就可以接收大量UDP数据包而不会丢失。首先要理解并

我正在编写一个GUI应用程序,它连续地从4Gb数据的FPGA板接收UDP数据包(应用程序是一个数据检索系统)

我创建了自己的类,继承自CAyncSocket,在接收消息时,我通过ReceiveFromAPI读取数据包,并将数据写入文件

由于数据包是从FPGA连续发送的(大约400k个1KB数据包),我的应用程序丢失了这些数据包。我只收到20万包。但当我用Wireshark监控时,所有数据包都被接收到


有谁能提出任何技术或算法来解决这个问题,这样我就可以接收大量UDP数据包而不会丢失。

首先要理解并接受的是,您不能保证不会丢弃任何UDP数据包。UDP传输层的一部分性质是,传输过程中的任何步骤都可以出于任何原因丢弃UDP数据包,并且这种情况会不时发生。在您的情况下,听起来Windows网络堆栈在从网卡接收到传入的UDP数据包后正在丢弃这些数据包,可能是因为与套接字关联的传入UDP数据包缓冲区太满,没有空间存储它们。例如,如果您的磁盘写入调用偶尔需要几毫秒才能返回,在此期间您的应用程序无法从UDP套接字读取更多数据,则可能会发生这种情况

也就是说,您可以做一些事情来降低数据包丢失的可能性

第一件(也是最简单的)事情是增加套接字的传入数据包缓冲区的大小,使用。这很有帮助,因为缓冲区越大,在网络堆栈完全填满缓冲区并开始丢弃数据包之前,程序从缓冲区读取数据包的时间就越长,因为它没有地方放置数据包

如果这还不足以满足您的需要,那么您可以做的另一件事是生成一个单独的线程,该线程只接收传入的UDP数据包,并将它们添加到队列中(供其他线程稍后处理)。因为这个线程除了接收UDP数据包外,什么也不做,所以当新数据包到达时,它能够快速响应,因此传入套接字缓冲区不太可能填满和溢出。如果可能的话,您可能希望以高优先级运行此线程,以便在其他线程或程序争夺CPU时间的情况下,它不太可能被CPU占用


如果您已经实现了上述两种方法,并且数据包丢失率仍然不可接受,那么您可能必须后退一步,重新评估您的方法。这可能包括从UDP协议切换到TCP,或者将代码重写为内核内驱动程序,或者切换到能够更好地保证响应时间的实时操作系统。

首先要理解并接受的是,您不能保证不会丢弃UDP包。UDP传输层的一部分性质是,传输过程中的任何步骤都可以出于任何原因丢弃UDP数据包,并且这种情况会不时发生。在您的情况下,听起来Windows网络堆栈在从网卡接收到传入的UDP数据包后正在丢弃这些数据包,可能是因为与套接字关联的传入UDP数据包缓冲区太满,没有空间存储它们。例如,如果您的磁盘写入调用偶尔需要几毫秒才能返回,在此期间您的应用程序无法从UDP套接字读取更多数据,则可能会发生这种情况

也就是说,您可以做一些事情来降低数据包丢失的可能性

第一件(也是最简单的)事情是增加套接字的传入数据包缓冲区的大小,使用。这很有帮助,因为缓冲区越大,在网络堆栈完全填满缓冲区并开始丢弃数据包之前,程序从缓冲区读取数据包的时间就越长,因为它没有地方放置数据包

如果这还不足以满足您的需要,那么您可以做的另一件事是生成一个单独的线程,该线程只接收传入的UDP数据包,并将它们添加到队列中(供其他线程稍后处理)。因为这个线程除了接收UDP数据包外,什么也不做,所以当新数据包到达时,它能够快速响应,因此传入套接字缓冲区不太可能填满和溢出。如果可能的话,您可能希望以高优先级运行此线程,以便在其他线程或程序争夺CPU时间的情况下,它不太可能被CPU占用

如果您已经实现了上述两种方法,并且数据包丢失率仍然不可接受,那么您可能必须后退一步,重新评估您的方法。这可能包括从UDP协议切换到TCP,或者将代码重写为内核内驱动程序,或者切换到能够更好地保证响应时间的实时操作系统