c++ 使用 recvmmsg 丢弃 udp 数据包
c++ drops udp packets with recvmmsg
我正在开发一个 c++ 程序,它通过以太网使用来自 FPGA 的 UDP 数据流。 FPGA 和我的以太网卡之间没有集线器或路由器。数据为10446 pps,速率为125350.0 kbps。
我的 C++ 应用程序使用专用线程和 recvmmsg 来清空数据。每个数据包的前 4 个字节都有一个序列号,后面是 1468 个字节的流数据。我正在使用 recvmmsg,我已经尝试 VLEN
(10,100) 和 MSG_WAITFORONE
、MSG_DONTWAIT
、0
的组合作为标志。
我看到的症状是这样的:
- 程序开始前,流运行固定速度。
- 当程序启动时,我有一个很短的初始阶段,其中
recvmmsg
的 return 值与 VLEN
相同。如果我理解正确,这是 Linux 内核缓冲区的耗尽。
- 在这之后,对于
recvmmsg
的return值,我总是得到一个1
的值
- 如果我对系统造成较小的负载(例如调整 gui 的大小 window)。我看到一丢丢 UDP 数据包,如缺少序列号所示。 (没有重新排序,只是丢失了)。
- During/after一滴,我没有得到更大的return值
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。这不是此特定应用程序的选项。谢谢。
增加接收套接字的接收缓冲区大小应该可以解决这个问题:
setsockopt (fd, IPPROTO_UDP, SO_RCVBUF, desired_receive_buffer_size);
文档 here.
我正在开发一个 c++ 程序,它通过以太网使用来自 FPGA 的 UDP 数据流。 FPGA 和我的以太网卡之间没有集线器或路由器。数据为10446 pps,速率为125350.0 kbps。
我的 C++ 应用程序使用专用线程和 recvmmsg 来清空数据。每个数据包的前 4 个字节都有一个序列号,后面是 1468 个字节的流数据。我正在使用 recvmmsg,我已经尝试 VLEN
(10,100) 和 MSG_WAITFORONE
、MSG_DONTWAIT
、0
的组合作为标志。
我看到的症状是这样的:
- 程序开始前,流运行固定速度。
- 当程序启动时,我有一个很短的初始阶段,其中
recvmmsg
的 return 值与VLEN
相同。如果我理解正确,这是 Linux 内核缓冲区的耗尽。 - 在这之后,对于
recvmmsg
的return值,我总是得到一个 - 如果我对系统造成较小的负载(例如调整 gui 的大小 window)。我看到一丢丢 UDP 数据包,如缺少序列号所示。 (没有重新排序,只是丢失了)。
- During/after一滴,我没有得到更大的return值
recvmmsg
- Wireshark/tcpdump 不显示任何缺失数据,所有序列号都存在。
1
的值
如果我观察 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。这不是此特定应用程序的选项。谢谢。
增加接收套接字的接收缓冲区大小应该可以解决这个问题:
setsockopt (fd, IPPROTO_UDP, SO_RCVBUF, desired_receive_buffer_size);
文档 here.