5

我每秒接收约 3000 个 UDP 数据包,每个数据包的大小约为 200 字节。我编写了一个 java 应用程序,它监听这些 UDP 数据包并将数据写入文件。然后服务器以先前指定的速率发送 15000 条消息。写入文件后,它仅包含约 3500 条消息。使用wireshark,我确认我的网络接口收到了所有15000条消息。之后我尝试更改套接字的缓冲区大小(最初是 8496 字节):

(java.net.MulticastSocket)socket.setReceiveBufferSize(32*1024);

该更改将保存的消息数量增加到约 8000 条。我不断将缓冲区大小增加到 1MB。之后,保存的消息数量达到了 ~14400。将缓冲区大小增加到更大的值不会增加保存的消息数量。我想我已经达到了允许的最大缓冲区大小。不过,我需要捕获我的网络接口接收到的所有 15000 条消息。

任何帮助,将不胜感激。提前致谢。

4

5 回答 5

5

闻起来像一个错误,很可能在您的代码中。如果 UDP 数据包通过网络传递,它们将在本地排队等待传递,正如您在 Wireshark 中看到的那样。也许您的程序在从其套接字读取时没有及时取得进展 - 是否有专门的线程来执行此任务?

通过检测程序丢失了哪些数据包,您可能会取得一些进展。如果所有丢失的数据包都是早期的,那么数据可能在程序等待接收它们之前就已经发送了。如果他们都晚了,也许它退出得太早了。如果它们定期进行,则您的代码中可能会出现一些问题,即循环接收数据包。等等

无论如何,您似乎对丢失的数据包异常焦虑。按照设计,UDP 不是一种可靠的传输方式。如果这些多播数据包的丢失对您的系统来说是一个问题(而不仅仅是出于性能原因您想解决的一个谜),那么系统设计就是错误的。

于 2011-11-25T10:08:47.453 回答
1

您似乎遇到的问题是您延迟写入文件。在写入文件(或在另一个线程中写入文件)之前,我会将所有数据读入内存

但是,如果无法要求再次发送数据包,就无法确保 100% 的数据包通过 UDP 接收(TCP 为您做的事情)

于 2011-11-25T10:09:31.947 回答
1

我看到您正在使用 UDP 发送文件内容。在 UDP 中,数据包的顺序是不确定的。如果您不担心顺序,则将所有数据包放入队列中,并让另一个线程处理队列并将内容写入文件。这样,套接字读取器线程不会因为文件操作而被阻塞。

于 2011-11-25T10:18:56.867 回答
0

接收缓冲区大小在操作系统级别配置。

例如在 Linux 系统上,sysctl -w net.core.rmem_max=26214400如本文 https://access.redhat.com/site/documentation/en-US/JBoss_Enterprise_Web_Platform/5/html/Administration_And_Configuration_Guide/jgroups-perf-udpbuffer.html

于 2014-02-12T23:30:24.803 回答
0

这是一个仅适用于 Windows 的答案,但网络控制器卡属性的以下更改在我们的用例中对丢包产生了巨大的影响。

我们正在消耗大约 200 Mbps 的 UDP 数据,并且在中等服务器负载下经历了大量的数据包丢失。

使用的网卡是华硕 ROG Aerion 10G卡,但我希望大多数高端网络控制器卡都具有类似的特性。您可以通过设备管理器->网卡->右键->属性->高级选项来访问它们。

1.增加接收缓冲区的数量:

默认值为 512;我们可以将它增加到 1024。在我们的例子中,接受了更高的设置,但是一旦超过 1024,网卡就会被禁用。在网卡级别拥有更多的可用缓冲区使系统对传输延迟的容忍度更高数据从网卡缓冲区到我们的应用程序最终可以读取数据的套接字缓冲区。

2. 将中断调节率设置为“关闭”:

如果我理解正确,中断审核会将多个“缓冲区填充”通知(通过中断)合并为一个通知。因此,CPU 将不那么频繁地被中断,并在每次中断期间获取多个缓冲区。这会减少 CPU 使用率,但会增加准备缓冲区在被获取之前被覆盖的机会,以防中断服务延迟。

此外,正如Len Holgate在评论中所建议的,我们增加了套接字缓冲区的大小(正如 OP 已经做的那样)并在套接字级别启用了循环缓冲,这也应该增加处理套接字缓冲区的延迟容忍度。

于 2019-04-17T19:12:15.223 回答