【问题标题】:Java SocketException: No buffer space availableJava SocketException:没有可用的缓冲区空间
【发布时间】:2011-06-15 19:37:11
【问题描述】:

我的 java 代码使用多个线程,每个线程运行一个 ServerSocket 并接受。 这些线程使用 java 套接字相互通信。 121 个线程都运行良好,但是如果我用 256 个线程运行相同的代码,我会遇到这个错误:

java.net.SocketException: No buffer space available (maximum connections reached?): listen failed
    at java.net.PlainSocketImpl.socketListen(Native Method)
    at java.net.PlainSocketImpl.listen(Unknown Source)
    at java.net.ServerSocket.bind(Unknown Source)
    at java.net.ServerSocket.<init>(Unknown Source)
    at java.net.ServerSocket.<init>(Unknown Source)

我用的是windows xp sp3,有几个这样的帖子(here ),但是没有人针对这个问题发布解决方案。我还安装了一个 windows 补丁来消除 TCP 连接的限制,但我没有解决我的问题。

【问题讨论】:

  • 你处理传入连接的速度够快吗?

标签: java buffer space socketexception


【解决方案1】:

消息说您的连接可能用完了。你检查过吗?您可以使用以下命令从命令行检查打开的套接字:

netstat -n

确保关闭两侧的所有套接字(在 finally 块中)。请记住,在您收到连接后,侦听套接字保持打开状态。不要太快地打开和关闭套接字(我会说它们不能立即重复使用,这可能与您的问题有关)。

为了获得更好的与套接字相关的性能,您可以使用 java.nio API,但它比 java.net 复杂得多。

【讨论】:

  • 谢谢,我通过更改 ServerSocket 调用解决了问题。我的错误是将积压值设置得太高。我不需要该服务器侦听超过 5-6 个连接。我替换了: ServerSocket sock=new ServerSocket(port,500);使用 ServerSocket sock=new ServerSocket(port,10);现在一切正常!
【解决方案2】:

This post我想可能会有你的答案。留下悬空的套接字会导致您达到最大值(这可能由 Windows 补丁无法修复的其他一些设置决定(例如 JVM 限制?)

附带说明,如果您使用这么多线程运行,那么使用 java.nio 而不是 java 的简单 Socket 和 ServerSocket 类很可能会更好。

This site 是一个非常好的教程,介绍了如何使用 java.nio 以及我如何学习它(以及查看 Sun/Oracle's Java NIO API),来自使用简单的 Socket 和 ServerSocket 编程。

具体来说,对您的事业有帮助的是使用选择器,它允许您以与 C++ select() 调用处理套接字相同的方式多路复用套接字 I/O。这意味着在您的套接字代码的核心,您可以减少大量线程处理套接字 I/O 的影响,并且只有一个线程直接与套接字交互。

【讨论】:

  • 第一个链接坏了。
【解决方案3】:

我通过更改 ServerSocket 调用解决了问题。我的错误是将积压值设置得太高。我不需要该服务器侦听超过 5-6 个连接。我替换了: ServerSocket sock=new ServerSocket(port,500);使用 ServerSocket sock=new ServerSocket(port,10);现在一切正常!

【讨论】:

    【解决方案4】:

    不知道你具体在做什么,这只是一个猜测,但我会提供这个以防其他人看到类似的问题。我在尝试打开太多 OUTGOING 连接时看到了这个错误。通过减小缓冲区大小,您限制了连接线程打开的连接数(当您达到缓冲区限制时,它们将被拒绝)。如果您仍然获得足够的吞吐量,那是一个很好的解决方案。但是,另一种解决方案是增加可用传出连接的数量,这可能会解决您的问题并提供更好的吞吐量。

    为此,您可以添加/修改 MaxUserPort 的注册表项。使用 regedit,找到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters 然后添加/修改键:MaxUserPort 以键入 DWORD 和一个高值,如 65534(十进制)

    有一个关于 MaxuserPort 的usoft tech article

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-14
      • 2010-11-16
      • 2016-08-08
      • 1970-01-01
      • 2011-05-25
      • 2017-03-18
      相关资源
      最近更新 更多