有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何最小化UDP数据包丢失

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

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

这一变化将保存的邮件数量增加到约8000条。我不断地将缓冲区大小增加到1MB。此后,保存的邮件数量达到14400条。将缓冲区大小增加到更大的值不会增加保存的消息数。我想我已经达到了允许的最大缓冲区大小。尽管如此,我仍然需要捕获我的网络接口接收到的所有15000条消息

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


共 (5) 个答案

  1. # 1 楼答案

    这是一个仅适用于Windows的答案,但网络控制器卡属性中的以下更改对我们的用例造成了显著的数据包丢失

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

    目前使用的网卡是华硕ROG Aerion 10G卡,但我预计大多数高端网络控制器卡都会暴露类似的属性。您可以通过设备管理器->;网卡->;右键单击->;房地产->;高级选项

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

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

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

    如果我理解正确,中断调节将多个“缓冲区填充”通知(通过中断)合并为一个通知。因此,CPU中断的频率会降低,并在每次中断期间获取多个缓冲区。这降低了CPU使用率,但增加了在提取前覆盖就绪缓冲区的机会,以防中断服务延迟

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

  2. # 2 楼答案

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

    但是,如果没有请求再次发送数据包的能力(TCP为您做的事情),就无法确保使用UDP接收100%的数据包

  3. # 4 楼答案

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

  4. # 5 楼答案

    闻起来像个bug,很可能是在你的代码里。如果UDP数据包通过网络传输,它们将在本地排队等待传输,正如您在Wireshark中看到的那样。也许你的程序在从套接字读取数据方面没有取得及时的进展——有专门的线程来完成这项任务吗

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

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