Squeak.ru - шаблоны программирования

Почему я получаю java.net.BindException: только одно использование каждого адреса сокета, если netstat говорит что-то еще?

  • Я запускаю свое приложение, которое использует сервер Jetty, используя порт 9000.
  • Затем я закрыл свое приложение с помощью Ctrl-C
  • Я проверяю с помощью «netstat -a» и вижу, что порт 9000 больше не используется.
  • Я перезапускаю свое приложение и получаю:
[ERROR,9/19 15:31:08] java.net.BindException: Only one usage of each socket address (protocol/network address/port) is normally permitted
[TRACE,9/19 15:31:08] java.net.BindException: Only one usage of each socket address (protocol/network address/port) is normally permitted
[TRACE,9/19 15:31:08]        at java.net.PlainSocketImpl.convertSocketExceptionToIOException(PlainSocketImpl.java:75)

[TRACE,9/19 15:31:08]        at sun.nio.ch.Net.bind(Net.java:101)
[TRACE,9/19 15:31:08]        at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:126)
[TRACE,9/19 15:31:08]        at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:77)
[TRACE,9/19 15:31:08]        at org.mortbay.jetty.nio.BlockingChannelConnector.open(BlockingChannelConnector.java:73)

[TRACE,9/19 15:31:08]        at org.mortbay.jetty.AbstractConnector.doStart(AbstractConnector.java:285)
[TRACE,9/19 15:31:08]        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
[TRACE,9/19 15:31:08]        at org.mortbay.jetty.Server.doStart(Server.java:233)
[TRACE,9/19 15:31:08]        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
[TRACE,9/19 15:31:08]        at ...

Это ошибка Java? Можно ли как-то избежать этого перед запуском сервера Jetty?

Редактировать #1 Вот наш код для создания нашего BlockingChannelConnector, обратите внимание на "setReuseAddress(true)":

    connector.setReuseAddress( true );
    connector.setPort( port );
    connector.setStatsOn( true );
    connector.setMaxIdleTime( 30000 );
    connector.setLowResourceMaxIdleTime( 30000 );
    connector.setAcceptQueueSize( maxRequests );
    connector.setName( "Blocking-IO Connector, bound to host " + connector.getHost() );

Может ли это быть как-то связано со временем простоя?

Правка #2 Следующая часть головоломки, которая может помочь или не помочь: при запуске приложения в режиме отладки (Eclipse) сервер запускается без проблем!!! Но проблема, описанная выше, воспроизводимо возникает при запуске приложения в режиме выполнения или в виде встроенного файла jar. Виски Танго Фокстрот?

Редактировать №3 (через 4 дня) — проблема все еще существует. Какие-нибудь мысли?

19.09.2008

  • Ваша машина имеет несколько интерфейсов? Если да, то к какому из них вы привязаны и на каком интерфейсе работал netstat -a? 19.09.2008

Ответы:


1

При первом вызове вашей программы она приняла хотя бы одно входящее соединение? Если это так, то то, что вы, скорее всего, видите, это задержка сокета.

Для лучшего объяснения откопайте копию TCP/IP, иллюстрированную Стивенсом.

alt text
(источник: кохала .com)

Но, насколько я понимаю, из-за того, что приложение не закрыло соединение должным образом (то есть ОБА клиент и сервер отправили свои последовательности FIN/ACK), сокет, который вы слушали, не может быть повторно использован до тех пор, пока соединение не будет считаться мертвым, так называемый 2MSL тайм-аут. Значение 1 MSL может варьироваться в зависимости от операционной системы, но обычно это не менее минуты, а обычно больше похоже на 5.

Лучший совет, который я слышал, чтобы избежать этого условия (кроме того, чтобы всегда правильно закрывать все сокеты при выходе), - это установить для параметра tcp SO_LINGER значение 0 на сокете вашего сервера во время фазы listen(). Как указывало свободное пространство, в java это метод setReuseAddress(true).

19.09.2008
  • нет, он не принял соединение. Заводится, тут же выключается. 19.09.2008
  • однако странно то, что временные рамки, о которых вы упоминаете (обычно не менее минуты, обычно больше 5), похоже, соответствуют проблеме... :-/ 19.09.2008

  • 2

    Возможно, вы захотите вызвать setReuseAddress(true) перед вызовом bind() для вашего объекта сокета. Это вызвано тем, что TCP-соединение сохраняется даже после закрытия сокета.

    19.09.2008
  • мы вызываем это на BlockingChannelConnector. см. отредактированный вопрос 19.09.2008

  • 3

    Я не уверен насчет Jetty, но я заметил, что иногда Tomcat не завершает работу корректно на некоторых наших Linux-серверах. В таких случаях Tomcat перезапустится, но не сможет использовать рассматриваемый порт, поскольку предыдущий экземпляр все еще привязан к нему. В таких случаях мы должны найти мошеннический процесс и явно убить его -9, прежде чем мы перезапустим Tomcat. Я не уверен, является ли это ошибкой Java или специфичной для Tomcat или JVM, которую мы используем.

    19.09.2008
  • ни один процесс не запущен после его закрытия с помощью Ctrl-C. Фактически мы используем одно и то же окно консоли для запуска нового процесса. 19.09.2008

  • 4

    Должен сказать, я также думал, что это обычная проблема, решаемая setReuseAddress(true). Однако сообщение об ошибке в этом случае обычно связано с тем, что JVM не может привязаться к порту. Я никогда раньше не видел опубликованного сообщения об ошибке. Поиск в Google, кажется, предполагает, что другой процесс прослушивает один или несколько (но не все) сетевых интерфейсов, и вы запрашиваете, чтобы ваш процесс привязывался ко всем интерфейсам, тогда как он может привязываться к некоторым (те, которые другой процесс не прослушивает д.), но не все. Хотя тут только угадаю...

    19.09.2008
    Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...