Java SocketException:没有可用的缓冲区空间

时间:2011-06-15 19:37:11

标签: java buffer space socketexception

我的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连接的限制,但我没有解决我的问题。

4 个答案:

答案 0 :(得分:5)

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

netstat -n

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

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

答案 1 :(得分:3)

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

作为旁注,如果您使用那么多线程运行,那么最好使用java.nio而不是java的简单Socket和ServerSocket类。

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

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

有关于MaxuserPort的usoft tech article