【发布时间】:2017-04-19 10:13:50
【问题描述】:
我正在开发一个应用程序,接收高达 900 Mb/s 的数据,通过 UDP(1036 字节数据报大小)传入。在“正常”情况下(没有系统负载和用户交互),一切正常:操作系统和我的应用程序都没有报告丢失的数据报。当我开始单击 Windows 资源管理器的文件夹树,更改其主显示窗格的内容时,数据报被删除。我通过使用 Windows 性能监视器并检查数据报有效负载中烘焙的序列号来观察这一点。 这会导致每次点击都会丢失数百个数据报。
接收器缓冲区大小增加(128 MB 操作系统,甚至更多用于我的应用程序)。我进一步观察到没有缓冲区达到其限制,如果调用
ioctlsocket(my_socket, FIONREAD, &readableBytes);
返回准确的字节数。最高观察值低于 2 MB。 我不确定哪些其他缓冲区可能溢出以及如何跟踪它们的状态。
该应用程序是使用 Qt 开发的。除了 UDP 接收线程之外,还使用了其他三个线程。当没有用户交互并且接收线程被切断时,它们都是空闲的。所有这些都是重现问题的每个测试设置的情况。
接收线程的第一次迭代使用了一个 Qt UDP 套接字,并检查了正确的序列号。
第二次迭代使用普通的 WinSock 调用 recv(...),并在另一个线程中检查序列号。这显然增加了线程的数量。两个线程都通过无锁队列进行通信,该队列完全能够处理呈现给它的读取和写入操作。然而,即使只有接收线程在运行(读取数据报并丢弃它们),也可能会观察到与上述相同的行为。
即使是具有多个接收器线程(也只有读取和丢弃)的实现也会显示相同的行为。
即使数据速率降至 330 Mb/s,也可能会出现此问题,但频率会降低。它会在更低的数据速率下消失。
是的,我知道 UDP 不保证传送,但数据包显然到达了我的机器,并在有充足的 CPU 时间和可用缓冲区空间的情况下被丢弃 - 至少可以这么说,这似乎很奇怪。
我想知道的:
- 这种行为有什么解释吗?
- 如果是这样,可能的解决方案是什么?
- 如果不是,可以通过什么检查来找出导致此问题的原因?
任何帮助或指导将不胜感激,谢谢!
【问题讨论】:
标签: c++ windows qt sockets network-programming