Jak uniknąć wyjątku NoRouteToHostException?

Ujawnienie: kod, nad którym pracuję, dotyczy zajęć uniwersyteckich.

Tło: Zadaniem, które próbuję wykonać, jest raportowanie wpływu różnych technik gwintowania. W tym celu napisałem kilka klas, które odpowiadają na żądanie klienta korzystającego z Java Sockets. Pomysł polega na zalaniu serwera żądaniami i zgłoszeniu, jak radzą sobie z tym różne strategie wątkowania. Każdy klient wykona 100 żądań, aw każdej iteracji zwiększymy liczbę klientów o 50, aż coś się zepsuje.

Problem: powtarzalnie i konsekwentnie występuje wyjątek:

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

Dzieje się tak w kilku scenariuszach, w tym wtedy, gdy zarówno klient, jak i serwer działają na localhost. Połączenia mogą zostać pomyślnie nawiązane przez pewien czas, wkrótce po próbie połączenia 150 klientów, których wyjątek został zgłoszony.

Moja pierwsza myśl była taka, że ​​może to być limit Linuksa dla otwartych deskryptorów plików (1024), ale nie sądzę. Sprawdziłem również, czy wszystkie połączenia między gniazdami są prawidłowo zamknięte (tj. Wewnątrz poprawnegofinally blok).

Waham się, czy opublikować kod, ponieważ nie jestem pewien, które części byłyby najbardziej trafne i nie chcę mieć ogromnej listy kodów w pytaniu.

Czy ktoś wcześniej się z tym spotkał? Jak mogę uniknąć wyjątku NoRouteToHostException?

EDYCJA (dalsze pytania są pisane kursywą)

Jak dotąd kilka dobrych odpowiedzi, które wskazują na Zakres Portu Efemerycznego lub RFC 2780. Oba sugerowałyby, że mam zbyt wiele otwartych połączeń. Wydaje się, że liczba połączeń, które należy wykonać, aby osiągnąć ten limit, sugeruje, że w pewnym momencie nie zamykam połączeń.

Po debugowaniu klienta i serwera zaobserwowano, że oba wywołały wywołanie metodymyJava-Net-SocketInstance.close(). Sugerowałoby to, że połączenia są zamykane (przynajmniej w wyjątkowym przypadku).Czy to poprawna sugestia?

Również,Czy istnieje oczekiwanie na poziomie systemu operacyjnego, aby porty ponownie stały się dostępne? Byłoby możliwe uruchomienie programu osobno dla każdego klienta 50+, gdyby wymagało to tylko krótkiego okresu (lub optymistycznie, uruchomienia polecenia) przed uruchomieniem następnej próby.

EDIT v2.0

Po otrzymaniu dobrych odpowiedzi zmodyfikowałem mój kod, aby użyć metody setReuseAddress (true) z każdym połączeniem Socket na kliencie. Nie przyniosło to pożądanego efektu i nadal jestem ograniczony do 250–300 klientów. Po zakończeniu programu uruchom polecenienetstat -a pokazuje, że w statusie TIME_WAIT istnieje wiele połączeń z gniazdami.

Moje założenie było takie, że jeśli gniazdo jest wTIME-WAIT status i został ustawiony za pomocąSO-REUSEADDR opcja, wszystkie nowe gniazda próbujące korzystać z tego portu będą mogły - jednak nadal otrzymuję wyjątek NoRouteToHostException.

Czy to jest poprawne? Czy jest jeszcze coś, co można zrobić, aby rozwiązać ten problem?

questionAnswers(6)

yourAnswerToTheQuestion