Раскрытие: код, над которым я работаю, - это курсовая работа в университете.
Справочная информация. Задача, которую я пытаюсь завершить, - сообщить о влиянии различных методов потоковой обработки. Для этого я написал несколько классов, которые отвечают на запрос от клиента с использованием Java Sockets. Идея состоит в том, чтобы нагрузить сервер запросами и сообщить о том, как справляются с этим различные стратегии потоков. Каждый клиент будет делать 100 запросов, и на каждой итерации мы увеличиваем количество клиентов на 50, пока что-то не сломается.
Проблема: повторяемо и последовательно возникает исключение:
Caused by: java.net.NoRouteToHostException: Cannot assign requested address at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
Это происходит в нескольких сценариях, в том числе, когда клиент и сервер работают на локальном хосте. Соединения могут быть успешно выполнены некоторое время, и вскоре после попытки подключения 150 клиентов, которые выбрасывают исключение.
Моя первая мысль заключалась в том, что это ограничение Linux для дескрипторов открытых файлов (1024), но я так не думаю. Я также проверил, что все соединения между сокетами закрыты должным образом (т.е. В правильном блоке finally
).
Я не решаюсь опубликовать код, потому что не уверен, какие части будут наиболее релевантными и не хотят иметь огромный список кода в вопросе.
Кто-нибудь сталкивался с этим раньше? Как я могу избежать исключения NoRouteToHostException?
EDIT (дополнительные вопросы выделены курсивом)
До сих пор есть хорошие ответы, которые указывают либо на Ephemeral Port Range, либо на RFC 2780. Оба из них предполагают, что у меня слишком много соединений. Для обоих он показывает, что количество соединений, которые необходимо сделать для достижения этого предела, предполагает, что в какой-то момент я не закрываю соединения.
После отладки как клиента, так и сервера, оба наблюдали, как ударил вызов метода myJava-Net-SocketInstance.close()
. Это предполагает, что соединения закрываются (по крайней мере, в не исключительном случае). Это правильное предложение?
Кроме того, существует ли уровень ОС, необходимый для возобновления доступа к портам? Было бы возможно запустить программу отдельно для каждого 50+ клиентов, если для выполнения следующей попытки просто потребуется короткий период (или оптимистично, запустив команду).
EDIT v2.0
Получив хорошие ответы, я изменил свой код, чтобы использовать метод setReuseAddress (true) с каждым соединением сокета, сделанным на клиенте. Это не имело желаемого эффекта, и я все еще ограничен 250-300 клиентами. После завершения программы выполнение команды netstat -a
показывает, что в статусе TIME_WAIT имеется много соединений сокетов.
Мое предположение заключалось в том, что если сокет находился в состоянии TIME-WAIT
и был установлен с опцией SO-REUSEADDR
, любые новые сокеты, пытающиеся использовать этот порт, могли бы - однако, я все еще получаю NoRouteToHostException.
Это правильно? Есть ли что-нибудь еще, что можно сделать для решения этой проблемы?