Divulgación: el código en el que estoy trabajando es para cursos universitarios.Cómo evitar una excepción NoRouteToHostException?
Antecedentes: la tarea que intento completar es informar sobre el efecto de las diferentes técnicas de enhebrado. Para hacer esto, he escrito varias clases que responden a una solicitud de un cliente que usa Java Sockets. La idea es inundar el servidor con solicitudes e informar sobre cómo las diferentes estrategias de enhebrado lidian con esto. Cada cliente hará 100 solicitudes, y en cada iteración aumentaremos la cantidad de clientes en 50 hasta que se rompa algo.
Problema: repetible y consistente, se produce una excepción:
Caused by: java.net.NoRouteToHostException: Cannot assign requested address at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
Esto ocurre en varios escenarios, incluyendo cuando tanto el cliente y el servidor se están ejecutando en el servidor local. Las conexiones se pueden realizar con éxito durante un tiempo; poco después de tratar de conectar 150 clientes, se produce la excepción.
Mi primer pensamiento fue que podría ser el límite de Linux para los descriptores de archivos abiertos (1024), pero no lo creo. También verifiqué que todas las conexiones entre los enchufes estuvieran cerradas correctamente (es decir, dentro de un bloque correcto finally
).
Tengo dudas en publicar el código porque no estoy seguro de qué partes serían las más relevantes, y no quiero tener una gran lista de códigos en la pregunta.
¿Alguien ha encontrado esto antes? ¿Cómo puedo evitar la NoRouteToHostException?
EDITAR (más preguntas están en cursiva)
Algunas buenas respuestas hasta el momento ese momento ya sea al El efímero de intervalos de puertos o RFC 2780. Ambos de los cuales podría sugerir que tengo demasiadas conexiones abiertas. Para ambos, parece que el número de conexiones que deben realizarse para alcanzar este límite sugiere que en algún momento no cierro las conexiones.
Al depurar tanto el cliente como el servidor, se ha observado que ambos métodos presionan la llamada al método myJava-Net-SocketInstance.close()
. Esto sugeriría que las conexiones se están cerrando (al menos en el caso no excepcional). ¿Es esta una sugerencia correcta?
Además, ¿hay un nivel de espera de sistema operativo necesario para que los puertos vuelvan a estar disponibles? Sería una posibilidad de ejecutar el programa un tiempo separado para cada 50+ clientes si solo requiriera un período corto (u optimista, ejecutando un comando) antes de ejecutar el siguiente intento.
EDITAR v2.0
Habiendo tomado las buenas respuestas proporcionadas, he modificado mi código para utilizar el método de setReuseAddress (verdadero) con cada conexión de socket hecho en el cliente. Esto no tuvo el efecto deseado, y todavía estoy limitado a 250-300 clientes. Una vez que finaliza el programa, ejecutar el comando netstat -a
muestra que hay muchas conexiones de socket en el estado TIME_WAIT.
Mi hipótesis era que si un enchufe estaba en el estado TIME-WAIT
, y se había establecido con la opción SO-REUSEADDR
, los nuevos sockets que intentan utilizar ese puerto serían capaces de - sin embargo, todavía estoy recibiendo el NoRouteToHostException.
¿Es esto correcto? ¿Hay algo más que se pueda hacer para resolver este problema?
@Grundlefleck Si todavía no lo hace, intente llamar al adaptador predeterminado Socket() para recuperar un socket desconectado. Luego setReuseAddress (verdadero). Luego conecta(). Desea decirle a la pila que reutilice la dirección antes de intentar enlazarla. – Duck
Anteriormente estaba llamando al constructor que conecta (Socket (host, port)) y cuando vi tu comentario, se encendió una bombilla, y me di una bofetada por ser un idiota ... pero no funcionó, y el problema sigue siendo :-( – Grundlefleck