【问题标题】:Java7 DatagramSocket.setReceiveBufferSize way different between Windows and Linux?Windows和Linux之间的Java7 DatagramSocket.setReceiveBufferSize方式不同?
【发布时间】:2012-10-19 23:40:33
【问题描述】:

在 Linux (Ubuntu 12.04) 和 Windows 7 上调用此代码会得到截然不同的结果:

DatagramSocket socket = new DatagramSocket(4445);
socket.setReceiveBufferSize(Integer.MAX_VALUE);
System.out.println("SO_RX_BUFFER SET TO:"+socket.getReceiveBufferSize());

Linux 你得到: SO_RX_BUFFER 设置为:131071

在 Windows 上你会得到: SO_RX_BUFFER 设置为:2147483647

为什么操作系统之间存在巨大差异?为什么linux的价值这么小?有没有办法增加 linux 缓冲区的大小?

【问题讨论】:

    标签: java network-programming operating-system udp


    【解决方案1】:

    这里发生的情况是主机操作系统的行为不同。

    • 在 Linux 案例中,操作系统对您可以从应用程序中请求的内容设置了上限。要解决此问题,您需要更改操作系统配置设置。这将需要“root”权限,并且不应由应用程序完成。

      This page 有一些关于 Linux 网络调优的基本信息。

    • 在 Windows 的情况下,操作系统要么不设置限制,要么(更有可能)静默覆盖用户请求的缓冲区大小(如果它大于操作系统施加的限制)。


    说了这么多,你需要想想你在这里做什么。缓冲的网络数据包(RX 和 TX)很可能必须保存在物理内存中。当您增加限制时,您会迫使操作系统为自己保留更多的 RAM 页面,从而减少可用于正常应用程序的内存。

    第二个问题是,如果基本问题是您的应用程序难以跟上进度,那么增加网络缓冲量可能是有害的。在最坏的情况下,您的应用程序将不断处理旧数据包,而新数据包将被丢弃。简而言之,额外的缓冲在没有(必然)消除数据丢失的情况下使延迟变得更糟。

    【讨论】:

      【解决方案2】:

      这似乎是重复的: Why changing value of SO_RCVBUF doesn't work?

      看起来 linux 有配置文件限制。

      添加以下内容:

      net.core.rmem_max = 16777216(或任何你想要的限制)

      到 /etc/sysctl.conf

      解决了问题。

      【讨论】:

      • 这与从 java 中看到的问题类似。
      猜你喜欢
      • 2015-09-15
      • 1970-01-01
      • 1970-01-01
      • 2013-12-01
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多