Gru*_*eck 59 java sockets networking exception-handling
披露:我正在处理的代码是大学课程.
背景:我要完成的任务是报告不同线程技术的效果.为此,我编写了几个类来响应客户端使用Java套接字的请求.我们的想法是向服务器发送请求并报告不同的线程策略如何处理这个问题.每个客户端将发出100个请求,并且在每次迭代中,我们将客户端数量增加50,直到出现故障.
问题:可重复且一致地发生异常:
Caused by: java.net.NoRouteToHostException: Cannot assign requested address
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
这种情况发生在几种情况下,包括客户端和服务器都在localhost上运行时.可以成功连接一段时间,尝试连接150个客户端后不久就会抛出异常.
我的第一个想法是它可能是Linux对打开文件描述符(1024)的限制,但我不这么认为.我还检查了套接字之间的任何和所有连接是否正确关闭(即在正确的finally块内).
我对发布代码犹豫不决,因为我不确定哪些部分最相关,并且不希望在问题中有大量代码.
有没有人遇到过这个?如何避免NoRouteToHostException?
编辑(进一步的问题是斜体)
到目前为止,一些好的答案指向短暂的端口范围或RFC 2780.这两个都表明我有太多的连接打开.对于两者而言,似乎需要达到此限制的连接数表明在某些时候我没有关闭连接.
调试了客户端和服务器后,两者都被观察到了方法调用myJava-Net-SocketInstance.close().这表明连接正在关闭(至少在非例外情况下).这是正确的建议吗?
此外,是否还需要等待操作系统级别才能再次使用端口?如果在运行下一次尝试之前只需要短时间(或乐观地运行命令),则可以为每个50多个客户端单独运行程序.
编辑v2.0
在提供了良好的答案后,我修改了我的代码,使用方法setReuseAddress(true)与客户端上的每个Socket连接.这没有达到预期的效果,我仍然限制在250-300个客户端.程序终止后,运行该命令会netstat -a显示TIME_WAIT状态中存在大量套接字连接.
我的假设是,如果套接字处于TIME-WAIT状态,并且已使用该SO-REUSEADDR选项设置,则任何尝试使用该端口的新套接字都能够 - 但是,我仍然收到NoRouteToHostException.
它是否正确? 还有什么办法可以解决这个问题吗?
ato*_*ice 52
你试过设置:
echo "1" >/proc/sys/net/ipv4/tcp_tw_reuse
Run Code Online (Sandbox Code Playgroud)
和/或
echo "1" >/proc/sys/net/ipv4/tcp_tw_recycle
Run Code Online (Sandbox Code Playgroud)
这些设置可能会使Linux重新使用TIME_WAIT套接字.不幸的是我找不到任何明确的文件.
sfu*_*ger 16
这可能有所帮助:
短暂端口范围的另一个重要分支是它限制了从一台机器到远程机器上特定服务的最大连接数!TCP/IP协议使用连接的4元组来区分连接,因此如果短暂端口范围仅为4000端口宽,则意味着一次只能有4000个从客户端计算机到远程服务的唯一连接.
所以也许你的可用端口用完了.要获取可用端口的数量,请参阅
$ cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000
Run Code Online (Sandbox Code Playgroud)
输出来自我的Ubuntu系统,我有28,232个端口用于客户端连接.因此,只要您拥有280多个客户,您的测试就会失败.
| 归档时间: |
|
| 查看次数: |
83672 次 |
| 最近记录: |