Como evitar uma NoRouteToHostException?
Divulgação: o código em que estou trabalhando é para cursos universitários.
Background: A tarefa que estou tentando concluir é informar sobre o efeito de diferentes técnicas de threading. Para fazer isso, escrevi várias classes que respondem a uma solicitação de um cliente usando Java Sockets. A ideia é inundar o servidor com solicitações e relatar como as diferentes estratégias de segmentação lidam com isso. Cada cliente fará 100 solicitações e, em cada iteração, aumentaremos o número de clientes em 50 até que algo seja interrompido.
Problema: repetitivamente e consistentemente, ocorre uma exceção:
Caused by: java.net.NoRouteToHostException: Cannot assign requested address at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
Isso acontece em vários cenários, incluindo quando o cliente e o servidor estão sendo executados no host local. Conexões podem ser feitas com sucesso por um tempo, é logo depois de tentar conectar 150 clientes que a exceção é lançada.
Meu primeiro pensamento foi que poderia ser o limite do Linux em descritores de arquivos abertos (1024), mas eu não penso assim. Eu também verifiquei que todas e quaisquer conexões entre os soquetes são fechadas corretamente (ou seja, dentro de um corretofinally
quadra).
Estou hesitante em postar o código porque não sei quais partes seriam as mais relevantes e não quero ter uma lista enorme de código na pergunta.
Alguém já passou por isso antes? Como posso evitar o NoRouteToHostException?
EDIT (outras questões estão em itálico)
Algumas boas respostas até agora que apontam para o The Ephemeral Port Range ou o RFC 2780. Ambos sugerem que eu tenho muitas conexões abertas. Para ambos, parece que o número de conexões que precisam ser feitas para atingir esse limite sugere que, em algum momento, não estou fechando conexões.
Tendo depurado o cliente e o servidor, ambos foram observados para acertar a chamada do métodomyJava-Net-SocketInstance.close()
. Isso sugeriria que as conexões estão sendo fechadas (pelo menos no caso não excepcional).Esta é uma sugestão correta?
Além disso,Existe uma espera no nível do sistema operacional necessária para que as portas fiquem disponíveis novamente? Seria uma possibilidade para executar o programa em um tempo separado para cada 50 + clientes, se ele exigiria apenas um curto período (ou otimista, executando um comando) antes de executar a próxima tentativa.
EDITAR v2.0
Tendo tomado as boas respostas fornecidas, modifiquei meu código para usar o método setReuseAddress (true) com cada conexão Socket feita no cliente. Isso não teve o efeito desejado e ainda estou limitado a 250 a 300 clientes. Depois que o programa terminar, executando o comandonetstat -a
mostra que há muitas conexões de soquete no status TIME_WAIT.
Minha suposição era que se uma tomada estivesse noTIME-WAIT
status, e tinha sido definido com oSO-REUSEADDR
opção, qualquer novo sockets tentando usar essa porta seria capaz - no entanto, ainda estou recebendo o NoRouteToHostException.
Isso está correto? Existe mais alguma coisa que possa ser feita para resolver este problema?