c++ - c++ 使用 recvmmsg 丢弃 udp 数据包
问题描述
我正在开发一个 c++ 程序,它通过以太网使用来自 FPGA 的 UDP 数据流。FPGA 和我的以太网卡之间没有集线器或路由器。数据为 10446 pps,速率为 125350.0 kbps。
我的 c++ 应用程序使用专用线程和 recvmmsg 来清空数据。每个数据包的前 4 个字节都有一个序列号,后面是 1468 个字节的流数据。我正在使用 recvmmsg 并且我已经尝试过VLEN
(10,100) 和 , 的组合MSG_WAITFORONE
作为MSG_DONTWAIT
标志0
。
我看到的症状是这样的:
- 在程序开始之前,流以固定的速度运行。
- 当程序启动时,我有一个短暂的初始期,其中的返回值
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。这不是此特定应用程序的选项。谢谢。
解决方案
增加接收套接字的接收缓冲区的大小应该可以解决这个问题:
setsockopt (fd, IPPROTO_UDP, SO_RCVBUF, desired_receive_buffer_size);
文档在这里。
推荐阅读
- javascript - PDF Blob 未显示带有 rest api、Angular 6 的内容
- php - php数据库单例不返回第二个结果
- javascript - 带有 Vue.js 的 jQuery - $(this) 在方法中不起作用
- java - Java 中的向下转换抛出 ClassCastException
- laravel - 如何在 Windows 中更改 Laravel 5 的默认 url
- javascript - Webflow 视频背景 - 静音/取消静音按钮
- excel - 将地理时间格式转换为 HH:MM:SS
- azure - Kubernetes 设置 Eviction Thresholds, system-reserved , kube-reserved
- r - 尝试使用 SMOTE 创建平衡训练集时出错
- javascript - 我只想显示两行第一行是标题和其他下拉选择的选项