Как узнать, на каком порту слушать программу - PullRequest
0 голосов
/ 06 января 2019

Я пишу программу чата с использованием сокетов и Java, и мне нужно указать порт, который прослушивают серверы.

Вот вопросы, которые у меня есть:

  1. Как я могу быть уверен, что этот порт всегда свободен?

  2. Имеет ли значение, если другая программа также прослушивает этот порт?

  3. Если порт должен быть свободен и порт по умолчанию занят, как я бы уведомил клиентов об изменении номера порта?

  4. Должен ли я просто сделать так, чтобы сервер продолжал пытаться привязать к новому порт, увеличивая номер порта, пока не найдет свободный порт?

Ответы [ 4 ]

0 голосов
/ 14 января 2019

Если это ваш сервер, на котором запущена программа, они вы должны решить, какой порт использовать, и убедиться, что он доступен (т.е. не используется другой программой). Чтобы проверить это, просто попробуйте bind() ваш ServerSocket на этом порту. Если вы получите IOException, порт, вероятно, уже используется (в Linux проверьте вывод netstat -anp | grep <port>, чтобы проверить, какая программа его использует).

Если вы не хотите / не можете использовать фиксированный порт, то вы всегда можете подключиться к порту 0, который автоматически назначит свободный порт. Затем вы можете получить назначенный порт с помощью getLocalPort().

Однако для того, чтобы клиенты могли подключаться к вашему серверу (который работает на «плавающем» порту), вам необходимо рекламировать его, например, через JNDI (предпочтительно в Java), LDAP, ... (см. @ Azee answer для примеров).

В качестве примечания обратите внимание, что параметры TCP SO_REUSEADDR / SO_REUSEPORT do not имеют то же значение , в зависимости от используемой ОС (не говоря уже о их (не) доступность).

0 голосов
/ 10 января 2019

Зарегистрируйтесь в IANA

Вы можете зарегистрировать свой порт в IANA. Вот список уже используемых портов.

https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt

Вы можете подумать

эй, я только один человек! Я не люблю угрожать международному авторитету!

Имейте в виду, что:

  1. 90% всех портов не назначены / зарезервированы.
  2. веб-сайт http://mobrien.com/ зарегистрировал порт 2031, и человек, который зарегистрировал порт, является частным лицом, а не даже программистом (и, возможно, уже мертвым сегодня).
0 голосов
/ 14 января 2019

Не могли бы вы описать архитектуру, которую вы пытаетесь построить? Где вы используете свой сервер и клиентов?

Мои предложения:

  1. Используйте один постоянный порт и настройте веб-сервер (например, - nginx) для маршрутизации запросов на этот порт в соответствии с доменом. Клиентам не нужно знать порты - только домен. Кроме того, это позволит не выставлять в сеть все порты - только те, которые необходимы (80, 443).

  2. При запуске попытайтесь определить свободный порт (вызовите netstat или просто увеличивайте номер порта до тех пор, пока служба не будет запущена), сохраните номер порта в локальном файле. Отправьте этот локальный файл с помощью веб-сервера - например, nginx - всегда порт 80 или 443 - как статические данные. Клиенты сначала получают номер порта по статическому URL, а затем подключаются к предоставленному порту.

  3. Использовать службу имен - например, - Spring Cloud - запустите его на отдельном сервере. Откройте бесплатный порт при запуске приложения, зарегистрируйте его в службе имен. Клиенты всегда будут запрашивать услугу именования в первую очередь. В качестве альтернативы вы можете просто использовать простой балансировщик (например, AWS Elastic Balancer + AWC EC2).

  4. Используйте Kubernetes - настройте «Сервис» на конкретном порту и запустите любое количество экземпляров вашего приложения в модулях - свободные порты будут обнаружены автоматически.

P.s. Вы не можете запустить несколько приложений на одном порту. Скорее всего, он даже не начнется.

0 голосов
/ 10 января 2019

Как я могу быть уверен, что этот порт всегда свободен?

Вы можете использовать "netstat", чтобы проверить, доступен порт или нет. Вы можете перечислить все порты, используемые службой через:

netstat -anp

Если вы хотите найти определенный порт, вы можете использовать:

netstat -anp | find "port number", например netstat -anp | find ":8080".

Имеет ли значение, если другая программа также прослушивает этот порт?

Исходя из традиционного подхода, да, для TCP вы можете одновременно иметь только одно приложение, прослушивающее один и тот же порт и один и тот же локальный IP-адрес. Вы можете использовать один и тот же порт, используя несколько локальных IP-адресов, используя несколько сетевых карт или виртуальные сетевые интерфейсы.

Однако, похоже, что при использовании опции сокета SO_REUSEPORT вы можете использовать его повторно, проверьте this для получения дополнительной информации.

Если порт должен быть свободен, а порт по умолчанию занят, как бы я уведомил клиентов об изменении номера порта? Должен ли я просто сделать так, чтобы сервер продолжал пытаться подключиться к новому порту, увеличивая номер порта, пока не найдет свободный порт?

Лично я бы выбрал порт, который всегда свободен, или небольшой список портов, которые, как я знал, будут обычно свободными, и попробовал бы один за другим.

Общие правила выбора порта включают выбор как минимум 4-значного числа и избегание значений, меньших 1024. Кроме того, даже если порт уже используется другой службой, вы можете переназначить его для прослушивания другого порта, его вашей сети.

...