【发布时间】:2010-12-07 00:45:04
【问题描述】:
披露:我正在编写的代码用于大学课程。
背景:我要完成的任务是报告不同线程技术的效果。为此,我编写了几个类,它们使用 Java 套接字响应来自客户端的请求。这个想法是用请求淹没服务器并报告不同的线程策略如何处理这个问题。每个客户端将发出 100 个请求,在每次迭代中,我们将客户端数量增加 50 个,直到出现问题。
问题:可重复且始终如一地发生异常:
引起:java.net.NoRouteToHostException:无法分配请求的地址 在 java.net.PlainSocketImpl.socketConnect(本机方法) 在 java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)这发生在几种情况下,包括客户端和服务器都在本地主机上运行时。连接一段时间可以成功,尝试连接150个客户端后很快就会抛出异常。
我的第一个想法是这可能是 Linux 对打开文件描述符 (1024) 的限制,但我不这么认为。我还检查了套接字之间的所有连接是否正确关闭(即在正确的finally 块内)。
我对发布代码犹豫不决,因为我不确定哪些部分最相关,并且不想在问题中列出大量代码。
以前有人遇到过这种情况吗?如何避免 NoRouteToHostException?
编辑(其他问题用斜体表示)
到目前为止,一些好的答案指向临时端口范围或 RFC 2780。这两者都表明我打开了太多连接。对于这两种情况,似乎需要建立的连接数才能达到此限制表明在某些时候我不会关闭连接。
在调试了客户端和服务器后,观察到两者都命中了方法调用myJava-Net-SocketInstance.close()。这表明连接正在关闭(至少在非异常情况下)。 这是一个正确的建议吗?
另外,是否需要等待操作系统级别的端口才能再次可用? 如果只需要很短的时间,则可以为每 50 多个客户端单独运行该程序在运行下一次尝试之前的一段时间(或者乐观地说,运行命令)。
编辑 v2.0
在接受了所提供的良好答案后,我修改了我的代码以使用 setReuseAddress(true) 方法与客户端上建立的每个 Socket 连接。这并没有达到预期的效果,我仍然限于 250-300 个客户。程序终止后,运行netstat -a命令显示有很多处于TIME_WAIT状态的socket连接。
我的假设是,如果套接字处于 TIME-WAIT 状态,并且已使用 SO-REUSEADDR 选项进行设置,则任何尝试使用该端口的新套接字都能够 - 但是,我仍然收到 NoRouteToHostException .
这是正确的吗? 还有什么办法可以解决这个问题吗?
【问题讨论】:
-
@Grundlefleck 如果您还没有这样做,请尝试调用默认的 Socket() ctor,以便返回未连接的套接字。然后设置重用地址(真)。然后连接()。您想告诉堆栈在尝试绑定之前重用该地址。
-
我之前调用了连接 (Socket(host,port)) 的构造函数,当我看到你的评论时,一个灯泡亮了,我为自己是个白痴打了自己一巴掌……但它没有不行,问题依然存在:-(
标签: java networking sockets exception-handling