如何在vc ++

时间:2016-02-01 06:44:09

标签: sockets udp

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

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

由于数据包是从FPGA连续发送的(大约400k包1KB数据),我的应用程序丢失了数据包。我只收到200k数据包。但是当我使用Wireshark进行监控时,会收到所有数据包。

任何人都可以建议任何技术或算法来解决这个问题,这样我就可以毫无损失地接收大量的UDP数据包。

1 个答案:

答案 0 :(得分:3)

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

也就是说,你可以采取一些措施来减少数据包的丢弃。

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

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

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