Почему я должен ждать isBound при выделении случайного сокета в Java?

Недавно у меня возникла проблема с библиотекой embedded-postgres . Пытался вручную выбрать свободный порт через

      new ServerSocket(0).getLocalPort()

но я где-то попадал в состояние гонки (мои тесты зависли при запуске второго набора тестов).

Затем я узнал, что сама библиотека имеет эту возможность (использовать случайный порт) и не имеет той проблемы, которая была у меня. Я проанализировал исходный код и обнаружил единственную разницу в том, что они проводят дополнительную проверку:

      try (ServerSocket socket = new ServerSocket(0)) {
    while(!socket.isBound()) {
        Thread.sleep(50);
    }
    return socket.getLocalPort();
}

Поэтому после того, как порт был рандомизирован, они ждут, пока он не будет привязан. Код, о котором я говорю.

Хотелось бы знать, зачем там этот код. В моем понимании «привязка» заключалась в том, что она равносильна «прослушиванию» данного порта, но здесь этого не может быть, поскольку этот код выполняется до запуска сервера. Фактически, сервер запустится (и свяжется) именно с этим портом. Это меня очень смущает.

1 ответ

Решение

Код в библиотеке - это исправление этой проблемы, причина которой:

.. похоже, что метод EmbeddedPostgres#detectPort может вызвать проблему, поскольку он не ожидает привязки сокета перед запросом порта, что приводит к тому, что ServerSocket # getLocalPort возвращает -1, как описано в документации.

Таким образом, вызов ServerSocket.getLocalPort() возвращает -1если сокет не привязан, и, по- видимому, это может произойти через некоторое время после вызова, хотя неясно, при каких обстоятельствах. Таким образом, код просто ждет, чтобы убедиться, что он привязан.

Однако в документации нигде не сказано, что new ServerSocket(0)не возвращает связанный сокет. В javadoc для ServerSocket(int port) говорится: «Создает сокет сервера, привязанный к указанному порту».

Однако у них была проблема, это единственное исправление , и я полагаю, это решило проблему ... так что просто очень непонятная документация в JDK?


Что касается привязки и прослушивания. Привязка - это часть, в которой вы назначаете адрес и порт, она все еще должна активно начать принимать соединения.

Другие вопросы по тегам