如何避免 NoRouteToHostException? [英] How to avoid a NoRouteToHostException?

查看:23
本文介绍了如何避免 NoRouteToHostException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

披露:我正在编写的代码用于大学课程.

背景:我要完成的任务是报告不同线程技术的效果.为此,我编写了几个类,它们使用 Java 套接字响应来自客户端的请求.这个想法是用请求淹没服务器并报告不同的线程策略如何处理这个问题.每个客户端将发出 100 个请求,并且在每次迭代中,我们将客户端数量增加 50,直到出现问题为止.

问题:可重复且一致地发生异常:

<前>引起:java.net.NoRouteToHostException:无法分配请求的地址在 java.net.PlainSocketImpl.socketConnect(Native Method)在 java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)

这在多种情况下都会发生,包括客户端和服务器都在本地主机上运行时.暂时可以成功连接,尝试连接150个客户端后很快就抛出异常.

我的第一个想法是这可能是 Linux 对打开文件描述符 (1024) 的限制,但我不这么认为.我还检查了套接字之间的所有连接是否已正确关闭(即在正确的 finally 块内).

我不愿发布代码,因为我不确定哪些部分最相关,并且不想在问题中列出大量代码.

有没有人遇到过这个?如何避免 NoRouteToHostException?

<小时>

编辑(其他问题用斜体表示)

到目前为止,一些很好的答案指向临时端口范围或 RFC 2780.这两者都表明我打开了太多连接.对于这两种情况,似乎需要建立的连接数才能达到此限制表明在某些时候我不会关闭连接.

在调试客户端和服务器后,观察到两者都调用了方法调用 myJava-Net-SocketInstance.close().这表明连接正在关闭(至少在非例外情​​况下).这是一个正确的建议吗?

此外,是否需要操作系统级别的等待才能使端口再次可用?如果只需要很短的时间,可以为每个 50 多个客户端单独运行该程序运行下一次尝试之前的周期(或者乐观地说,运行命令).

<小时>

编辑 v2.0

接受了提供的好答案后,我修改了我的代码,以对客户端上建立的每个 Socket 连接使用 setReuseAddress(true) 方法.这并没有达到预期的效果,我仍然仅限于 250-300 个客户端.程序终止后,运行netstat -a命令,发现有很多处于TIME_WAIT状态的socket连接.

我的假设是,如果套接字处于 TIME-WAIT 状态,并且已使用 SO-REUSEADDR 选项进行设置,则任何尝试使用该状态的新套接字端口将能够 - 但是,我仍然收到 NoRouteToHostException.

这是正确的吗?还有什么办法可以解决这个问题吗?

解决方案

您是否尝试过设置:

echo "1" >/proc/sys/net/ipv4/tcp_tw_reuse

和/或

echo "1" >/proc/sys/net/ipv4/tcp_tw_recycle

这些设置可能会使 Linux 重新使用 TIME_WAIT 套接字.很遗憾,我找不到任何权威文档.

Disclosure: the code I'm working on is for university coursework.

Background: The task I'm trying to complete is to report on the effect of different threading techniques. To do this I have written several classes which respond to a request from a client using Java Sockets. The idea is to flood the server with requests and report on how different threading strategies cope with this. Each client will make 100 requests, and in each iteration we're increasing the number of clients by 50 until something breaks.

Problem: repeatably, and consistently, an exception occurs:

Caused by: java.net.NoRouteToHostException: Cannot assign requested address
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)

This happens in several scenarios, including when both the client and server are running on localhost. Connections can be made successfully for a while, it's soon after trying to connect 150 clients that the exception is thrown.

My first thought was that it could be Linux's limit on open file descriptors (1024) but I don't think so. I also checked that any and all connections between the sockets are closed properly (i.e. within a correct finally block).

I'm hesitant to post the code because I'm not sure which parts would be the most relevant, and don't want to have a huge listing of code in the question.

Has anyone come across this before? How can I avoid the NoRouteToHostException?


EDIT (further questions are italicised)

Some good answers so far which point to either the The Ephemeral Port Range or RFC 2780. Both of which would suggest that I have too many connections open. For both it appears the number of connections which need to be made to reach this limit suggest that at some point I'm not closing connections.

Having debugged both client and server, both have been observed to hit the method call myJava-Net-SocketInstance.close(). This would suggest that connections are being closed (at least in the non-exceptional case). Is this a correct suggestion?

Also, is there an OS level wait required for ports to become available again? It would be a possibility to run the program a separate time for each 50+ clients if it would just require a short period (or optimistically, running a command) before running the next attempt.


EDIT v2.0

Having taken the good answers provided, I modified my code to use the method setReuseAddress(true) with every Socket connection made on the client. This did not have the desired effect, and I am still limited to 250-300 clients. After the program terminates, running the command netstat -a shows that there is a lot of socket connections in the TIME_WAIT status.

My assumption was that if a socket was in the TIME-WAIT status, and had been set with the SO-REUSEADDR option, any new sockets attempting to use that port would be able to - however, I am still receiving the NoRouteToHostException.

Is this correct? Is there anything else which can be done to solve this problem?

解决方案

Have you tried setting:

echo "1" >/proc/sys/net/ipv4/tcp_tw_reuse

and/or

echo "1" >/proc/sys/net/ipv4/tcp_tw_recycle

These settings may make Linux re-use the TIME_WAIT sockets. Unfortunately I can't find any definitive documentation.

这篇关于如何避免 NoRouteToHostException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆