Java SocketException:没有可用的缓冲区空间
我的java代码使用几个线程,每个线程运行一个ServerSocket并进入accept。 这些线程使用java套接字相互通信。121个线程都可以正常工作,但如果我使用256个线程运行相同的代码,则会出现以下错误:Java SocketException:没有可用的缓冲区空间,java,buffer,space,socketexception,Java,Buffer,Space,Socketexception,我的java代码使用几个线程,每个线程运行一个ServerSocket并进入accept。 这些线程使用java套接字相互通信。121个线程都可以正常工作,但如果我使用256个线程运行相同的代码,则会出现以下错误: java.net.SocketException: No buffer space available (maximum connections reached?): listen failed at java.net.PlainSocketImpl.socketListen
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)
java.net.SocketException:没有可用的缓冲区空间(达到最大连接数?):侦听失败
位于java.net.PlainSocketImpl.socketListen(本机方法)
位于java.net.PlainSocketImpl.listen(未知源)
位于java.net.ServerSocket.bind(未知源)
位于java.net.ServerSocket。(未知源)
位于java.net.ServerSocket。(未知源)
我使用的是WindowsXPSP3,有好几篇类似这样的文章(),但是没有人针对这个问题发表过解决方案。我还安装了一个windows修补程序,用于删除TCP连接限制,但我没有解决我的问题。我想可能有你的答案。保持挂起的套接字将导致达到最大值(这可能由windows修补程序未修复的其他设置决定(例如JVM限制?)
作为补充说明,如果您使用那么多线程运行,那么很可能使用java.nio比使用java的简单Socket和ServerSocket类更好
这是一个非常好的教程,介绍了如何使用java.nio,以及我是如何通过使用简单的Socket和ServerSocket编程来学习它的(以及查看)
具体来说,帮助你的原因是使用选择器,它允许你以与C++选择()相同的方式多路复用你的套接字I/O。调用与套接字一起工作。这意味着在套接字代码的核心,您可以减少大量线程处理套接字I/O的影响,并且只有一个线程直接与套接字交互。消息说您可能正在耗尽连接。您检查了吗?您可以从e命令行使用:
netstat -n
确保您正在关闭两侧的所有套接字(在finally块中)。请记住,侦听套接字在收到连接后保持打开状态。不要太快地打开和关闭套接字(我想说,它们无法立即重用,这可能与您的问题有关)
为了获得更好的套接字相关性能,您可以使用java.nio API,但它比java.net复杂得多。我通过更改ServerSocket调用解决了这个问题。我的错误是将backlog值设置得太高。我不需要服务器侦听超过5-6个连接。我替换了:ServerSocket sock=new ServerSocket(端口,500);带ServerSocket sock=新的ServerSocket(端口,10);现在一切正常了!不知道您具体在做什么,这只是一个猜测,但我会提供这一点,以防其他人看到类似的问题。我在尝试打开太多传出连接时看到了此错误。通过减小缓冲区大小,您限制了连接区域打开的连接数ds(当您达到缓冲区限制时,它们将被拒绝)。如果您仍然获得足够的吞吐量,这是一个很好的解决方案。但是,另一个解决方案是增加可用的传出连接数,这可能会解决您的问题并提供更好的吞吐量 为此,您可以添加/修改MaxUserPort的注册表项。使用regedit,找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters,然后添加/mod key:MaxUserPort以键入DWORD和高值,如65534(十进制)
有一个关于MaxuserPort的问题。您处理传入连接足够快吗?谢谢,我通过更改ServerSocket调用解决了这个问题。我的错误是将backlog值设置得太高。我不需要服务器侦听超过5-6个连接。我替换了:ServerSocket sock=new ServerSocket(端口,500);使用ServerSocket sock=new ServerSocket(端口,10);现在一切正常!第一个链接断开。