以高数据包速率最小化丢弃的UDP数据包(Windows 10)

问题描述 投票:1回答:1

重要说明:我知道UDP是不可靠的协议。但是,由于我不是提供数据的设备的制造商,因此,我只能尽量减少影响。因此,请不要再发布有关UDP不可靠的任何声明。我需要一些建议以将损失降到最低。

我已经实现了一个应用程序C ++,该应用程序需要在短时间内接收大量UDP数据包,并且需要在Windows(Winsock)下工作。该程序可以工作,但如果每个UDP流的数据速率(或数据包速率)达到一定水平,则似乎会丢弃数据包。请注意,我无法更改摄像头接口以使用TCP。

详细信息:这是千兆位以太网摄像机的客户端,该摄像机使用UDP数据包将其图像发送到计算机。每台摄像机的数据速率通常接近网络接口的容量(每秒约120 MB),这意味着即使使用8KB巨型帧,每台摄像机的数据包速率仍在10'000至15,000。目前,我们已经将4台摄像机连接到一台计算机上……这意味着每秒最多可传输6万个数据包。

该软件可同时处理所有摄像机,并且每个摄像机的流接收器实现为单独的线程,并且具有自己的接收UDP套接字。在某个帧速率下,该软件似乎每隔几分钟就会丢失一些UDP帧(即使网络容量仅使用了约60-70%)。

硬件详细信息

  • 相机均来自国外制造商!它们通过以太网将UDP流发送到可配置的UDP端点。没有TCP支持...
  • 摄像机通过它们自己的专用网络接口连接(1GBit / s)
  • 直接连接,未使用任何开关(!)
  • 电缆是CAT6e或CAT7

实施细节

到目前为止,我将SO_RCVBUF设置为较大的值:

int32_t rbufsize = 4100 * 3100 * 2; // two 12 MP images
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&rbufsize, sizeof(rbufsize)) == -1) {
    perror("SO_RCVBUF");
    throw runtime_error("Could not set socket option SO_RCVBUF.");
}

不会引发错误。因此,我认为该值被接受。我还使用以下代码将主进程的优先级设置为HIGH-PRIORITY_CLASS:

SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); 

但是,我没有发现更改线程优先级的任何可能性。在设置进程优先级之后创建线程...

接收器线程使用阻塞IO一次接收一个数据包(超时时间为1000毫秒,以允许线程对全局关闭信号做出反应)。如果接收到数据包,则将其存储在缓冲区中,循环立即继续接收任何其他数据包。

问题

还有其他方法可以减少丢包的可能性吗?是否有可能一次调用接收套接字缓冲区中存储的所有数据包? (我不需要有关发送方的任何信息;只需要包含的有效负载即可)也许,您也可以建议一些注册表/网卡设置来检查...

c++ sockets networking udp winsock
1个回答
0
投票
  • IOCP和WSARecv处于重叠模式,您可以设置约60k WSARecv
  • 在处理GetQueuedCompletionStatus的线程上处理数据,并在该线程中执行WSARecv以补偿接收数据时所使用的那个]

请注意,您的udp数据包大小应保持在其MTU之下,这将导致丢弃,具体取决于相机和软件之间的所有网络硬件

  • 编写一些模仿摄像机的UDP测试器以测试网络,以确保硬件将支持负载。

https://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancediomethod5e.html

© www.soinside.com 2019 - 2024. All rights reserved.