Divulgation : le code sur lequel je travaille est destiné à un cours universitaire.
Historique : La tâche que j'essaie d'accomplir est de rendre compte de l'effet de différentes techniques de threading. Pour ce faire, j'ai écrit plusieurs classes qui répondent à une requête d'un client en utilisant des Java Sockets. L'idée est d'inonder le serveur de requêtes et d'étudier comment les différentes stratégies de threading y font face. Chaque client fera 100 demandes, et à chaque itération, nous augmentons le nombre de clients de 50 jusqu'à ce que quelque chose se casse.
Problème : de manière répétée et constante, une exception se produit :
Caused by: java.net.NoRouteToHostException: Cannot assign requested address
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
Cela se produit dans plusieurs scénarios, notamment lorsque le client et le serveur fonctionnent tous deux sur localhost. Les connexions peuvent être établies avec succès pendant un certain temps, mais c'est peu après avoir essayé de connecter 150 clients que l'exception est levée.
J'ai d'abord pensé qu'il pouvait s'agir de la limite imposée par Linux aux descripteurs de fichiers ouverts (1024), mais je ne le pense pas. J'ai également vérifié que toutes les connexions entre les sockets sont fermées correctement (c'est-à-dire dans un délai correct d'un an). finally
bloc).
J'hésite à poster le code parce que je ne suis pas sûr des parties qui seraient les plus pertinentes, et je ne veux pas avoir une énorme liste de code dans la question.
Quelqu'un a-t-il déjà rencontré ce problème ? Comment puis-je éviter l'exception NoRouteToHostException ?
EDIT (les autres questions sont en italique)
Quelques bonnes réponses jusqu'à présent qui pointent vers la gamme de ports éphémères ou la RFC 2780. Les deux suggèrent que j'ai trop de connexions ouvertes. Dans les deux cas, il semble que le nombre de connexions nécessaires pour atteindre cette limite suggère qu'à un moment donné, je ne ferme pas les connexions.
Après avoir débogué à la fois le client et le serveur, on a constaté qu'ils utilisent tous deux l'appel de méthode myJava-Net-SocketInstance.close()
. Cela suggère que les connexions sont fermées (au moins dans le cas non exceptionnel). Cette suggestion est-elle correcte ?
Aussi, Y a-t-il une attente au niveau du système d'exploitation pour que les ports soient à nouveau disponibles ? Il serait possible d'exécuter le programme une fois séparée pour chaque 50+ clients si cela ne nécessitait qu'une courte période (ou de manière optimiste, l'exécution d'une commande) avant d'exécuter la prochaine tentative.
EDIT v2.0
Ayant pris connaissance des bonnes réponses fournies, j'ai modifié mon code pour utiliser la méthode setReuseAddress(true) avec chaque connexion Socket effectuée sur le client. Cela n'a pas eu l'effet escompté, et je suis toujours limité à 250-300 clients. Après la fin du programme, l'exécution de la commande netstat -a
montre qu'il y a beaucoup de connexions de socket dans l'état TIME_WAIT.
Je supposais que si une prise se trouvait dans la section TIME-WAIT
et avait été fixé avec le SO-REUSEADDR
tous les nouveaux sockets qui tentent d'utiliser ce port pourront le faire. Cependant, je reçois toujours l'exception NoRouteToHostException.
Est-ce correct ? Y a-t-il autre chose à faire pour résoudre ce problème ?