C ++使用recvmmsg丢弃udp数据包

时间:2019-04-11 22:10:45

标签: c++ sockets udp

我正在开发一个c ++程序,该程序通过以太网使用来自FPGA的UDP数据流。 FPGA和我的以太网卡之间没有集线器或路由器。数据为10446 pps,速率为125350.0 kbps。

我的c ++应用程序使用专用线程和recvmmsg清空数据。每个数据包的序号为前4个字节,后跟1468个字节的流数据。我正在使用recvmmsg,并且尝试使用VLEN(10,100)和MSG_WAITFORONEMSG_DONTWAIT0的组合来标记。

我看到的症状是:

  • 程序启动之前,流以固定速度运行。
  • 程序启动时,我的初始时间很短,其中recvmmsg的返回值与VLEN相同。如果我理解正确,这就是Linux内核缓冲区的消耗。
  • 此后,我总是得到1的返回值recvmmsg
  • 如果我在系统上造成小的负载(例如,调整gui窗口的大小)。我看到丢失了UDP数据包,如缺少序列号所示。 (没有重新排序,只是丢失了)。
  • 在下降期间/之后,recvmmsg的返回值没有增加
  • Wireshark / tcpdump不显示任何丢失的数据,所有序列号都存在。

如果我看到netstat -suna的输出,我会看到RcvbufErrors:的值增加。

如果我看到ifconfig的输出,则看不到任何丢弃的数据包(RX packets:602492703 errors:0 dropped:0 overruns:0 frame:0)。

这些是我的问题:

  • 为什么在掉线情况下,我从recvmmsg收到的数据包从来没有超过一个?
  • wireshark为什么能够捕获数据包,但我的c ++无法捕获数据包?
  • 我可以使用哪些工具更好地了解为什么要放弃?

我尝试调整以下可调参数:

  • sysctl -w net.core.netdev_max_backlog=10000
  • sysctl -w net.core.rmem_max=9926214400

请不要建议我切换到TCP。这不是此特定应用程序的选项。谢谢。

1 个答案:

答案 0 :(得分:2)

增加接收套接字的接收缓冲区的大小应解决此问题:

setsockopt (fd, IPPROTO_UDP, SO_RCVBUF, desired_receive_buffer_size);

文档here