Подтвердить что ты не робот

Может ли два приложения прослушивать один и тот же порт?

Может ли два приложения на одном компьютере связываться с одним и тем же портом и IP-адресом? Сделав еще один шаг, может ли одно приложение прослушивать запросы, поступающие с определенного IP-адреса, а другое - на другой удаленный IP-адрес? Я знаю, что у меня может быть одно приложение, которое запускает два потока (или вилки), чтобы иметь подобное поведение, но могут ли два приложения, которые не имеют ничего общего, сделать то же самое?

4b9b3361

Ответ 1

Ответ зависит от того, какая ОС рассматривается. В общем, хотя:

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

Для UDP (Multicasts) несколько приложений могут подписаться на один и тот же порт.

Изменение: Начиная с Linux Kernel 3.9 и более поздних версий, поддержка нескольких приложений, прослушивающих один и тот же порт, была добавлена с использованием опции SO_REUSEPORT. Более подробная информация доступна на этой статье lwn.net.

Ответ 2

Да (для TCP) вы можете использовать две программы в одном и том же сокете, если программы предназначены для этого. Когда сокет создается первой программой, убедитесь, что параметр SO_REUSEADDR установлен в гнездо перед bind(). Однако это может быть не то, что вы хотите. То, что это делает, - это входящее TCP-соединение, будет направлено на одну из программ, а не на обе, поэтому она не дублирует соединение, а просто позволяет двум программам обслуживать входящий запрос. Например, веб-серверы будут иметь несколько процессов, все прослушивая порт 80, а O/S отправляет новое соединение процессу, который готов принять новые подключения.

SO_REUSEADDR

Разрешает другим сокетам bind() к этому порту, если только к нему не подключен активный слушающий сокет. Это позволяет обойти эти сообщения об ошибке "Адрес уже используется" при попытке перезагрузить сервер после сбоя.

Ответ 3

В принципе, нет.

Он не написан на камне; но это так, как написано все API: приложение открывает порт, получает к нему дескриптор, и ОС уведомляет его (через этот дескриптор), когда приходит клиентское соединение (или пакет в случае UDP).

Если ОС разрешило двум приложениям открыть один и тот же порт, как узнать, какой из них уведомлять?

Но... есть способы обойти это:

  • Как отметил Jed , вы можете написать процесс "master", который будет единственным, кто действительно слушает порт и уведомляет других, используя любую логику хочет отделить запросы клиентов.
    • В Linux и BSD (по крайней мере) вы можете настроить "переназначение" правил, которые перенаправляют пакеты из "видимого" порта в разные (где приложения прослушиваются), в соответствии с любыми сетевыми критериями (возможно, сеть происхождения, или некоторые простые формы балансировки нагрузки).

Ответ 4

Да.

  • Несколько сокетов TCP, все связанные с одним и тем же портом, могут сосуществовать, если все они связаны с разными локальными IP-адресами. Клиенты могут подключаться к тому, что им нужно. Это исключает 0.0.0.0 (INADDR_ANY).

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

  • Несколько сокетов UDP, все связанные с одним и тем же портом, могут сосуществовать при условии того же условия, что и в (1), или все они имеют параметр SO_REUSEADDR, установленный перед привязкой.

  • TCP-порты и порты UDP занимают разные пространства имен, поэтому использование порта для TCP не исключает его использования для UDP и наоборот.

Ссылка: Стивенс и Райт, Иллюстрированный TCP/IP, том II.

Ответ 5

Да Определенно. Насколько я помню Начиная с версии ядра 3.9 (не уверен в версии) появилась поддержка SO_REUSEPORT. SO_RESUEPORT позволяет привязывать к одному и тому же порту и адресу. Пока первый сервер устанавливает этот параметр перед привязкой его сокета.

Он работает как для TCP, так и UDP. Для получения дополнительной информации см. Ссылку: SO_REUSEPORT

Примечание. Принятый ответ больше не выполняется по моему мнению.

Ответ 6

Нет. Только одно приложение может привязываться к порту за раз, а поведение, если привязка принудительно, является неопределенной.

С многоадресными сокетами, которые звучат как нигде рядом с тем, что вы хотите - более одного приложения могут связываться с портом, пока SO_REUSEADDR устанавливается в каждом параметре сокета.

Вы можете выполнить это, написав "главный" процесс, который принимает и обрабатывает все подключения, а затем передает их двум вашим приложениям, которым необходимо прослушивать один и тот же порт. Это тот подход, который используют веб-серверы и такие, поскольку многие процессы требуют прослушивания 80.

Помимо этого, мы вдаваемся в подробности - вы отметили как TCP, так и UDP, и что это такое? Кроме того, какая платформа?

Ответ 7

Другим способом является использование программы, прослушивающей в одном порту, которая анализирует вид трафика (ssh, https и т.д.), который перенаправляет внутренне на другой порт, на котором прослушивается "реальная" услуга.

Например, для Linux, sslh: https://github.com/yrutschle/sslh

Ответ 8

У вас может быть одно приложение, прослушивающее один порт для одного сетевого интерфейса. Поэтому вы можете:

  • httpd прослушивание дистанционно доступного интерфейса, например. 192.168.1.1:80
  • прослушивание другого демона 127.0.0.1:80

Пример использования может состоять в использовании httpd в качестве балансировки нагрузки или прокси.

Ответ 9

Если хотя бы один из удаленных IP-адресов уже известен, статический и посвященный разговору только с одним из ваших приложений, вы можете использовать правило iptables (table nat, chain PREROUTING) для перенаправления входящего трафика с этого адреса на "общий", локальный порт на любой другой порт, где приложение действительно прослушивается.

Ответ 10

Когда вы создаете TCP-соединение, вы запрашиваете подключение к определенному TCP-адресу, который представляет собой комбинацию IP-адреса (v4 или v6, в зависимости от используемого протокола) и порта.

Когда сервер прослушивает соединения, он может сообщить ядру, что он хочет прослушивать определенный IP-адрес и порт, то есть один TCP-адрес, или на одном и том же порту на каждом из IP-адресов хоста (обычно указывается с помощью IP-адреса). 0.0.0.0), который эффективно прослушивает множество разных "TCP-адресов" (например, 192.168.1.10:8000, 127.0.0.1:8000 и т.д.)

Нет, два приложения не могут прослушивать один и тот же "TCP-адрес", потому что, когда приходит сообщение, как ядро узнает, какое приложение должно передать сообщение?

Однако в большинстве операционных систем вы можете настроить несколько IP-адресов на одном интерфейсе (например, если у вас есть 192.168.1.10 на интерфейсе, вы также можете настроить 192.168.1.11, если никто другой в сети не использует его) и в этих случаях у вас могут быть отдельные приложения, прослушивающие порт 8000 на каждом из этих двух IP-адресов.

Ответ 11

Да и нет. Только одно приложение может активно прослушивать порт. Но это приложение может завязать его связь с другим процессом. Таким образом, вы можете иметь несколько процессов, работающих на одном и том же порту.

Ответ 12

Да.

Из этой статьи:
https://lwn.net/Articles/542629/

Новая опция сокета позволяет нескольким сокетам на одном хосте привязываться к одному и тому же порту

Ответ 13

Если по приложениям вы имеете в виду несколько процессов, то да, но обычно НЕТ.  Например, сервер Apache запускает несколько процессов на одном и том же порту (как правило, 80). Это делается путем назначения одного из процессов для фактического привязки к порту, а затем использования этого процесса для передачи обслуживания для различных процессов, которые принимают соединения.

Ответ 14

Вы можете заставить два приложения прослушивать один и тот же порт на одном и том же сетевом интерфейсе.

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

Если у вас есть слуховой сокет в процессе приложения, а вы fork этот процесс, сокет будет унаследован, так что технически теперь будут два процесса прослушивания одного и того же порта.

Ответ 15

Я пробовал следующее: socat:

socat TCP-L:8080,fork,reuseaddr -

И хотя я не подключался к сокету, я не могу слушать дважды на одном и том же порту, несмотря на параметр reuseaddr.

Я получаю это сообщение (чего я ожидал раньше):

2016/02/23 09:56:49 socat[2667] E bind(5, {AF=2 0.0.0.0:8080}, 16): Address already in use

Ответ 16

Просто чтобы поделиться тем, что упомянул @jnewton. Я запустил nginx и встроенный процесс tomcat на моем Mac. Я вижу, как процесс запускается на 8080.

LT<XXXX>-MAC:~ b0<XXX>$ sudo netstat -anp tcp | grep LISTEN
tcp46      0      0  *.8080                 *.*                    LISTEN     
tcp4       0      0  *.8080                 *.*                    LISTEN   

Ответ 17

Короткий ответ:

Идем по ответу здесь. Вы можете прослушивать два приложения на одном IP-адресе и номер порта, поэтому один из портов является UDP-портом, а другой - TCP-портом.

Объяснение:

Концепция порта имеет отношение к транспортному уровню стека TCP/IP, поэтому, пока вы используете разные протоколы транспортного уровня стека, вы можете прослушивать несколько процессов в одной и той же комбинации <ip-address>:<port>.

Одно сомнение в том, что у людей есть два приложения, работающих в одной и той же комбинации <ip-address>:<port>, как будет работать клиент, работающий на удаленной машине, между двумя? Если вы посмотрите на заголовок пакета IP-уровня (https://en.wikipedia.org/wiki/IPv4#Header), вы увидите, что биты с 72 по 79 используются для определения протокола, это как различие может быть сделано.

Если, однако, вы хотите иметь два приложения в одной и той же комбинации TCP <ip-address>:<port>, тогда ответ будет отрицательным (интересным упражнением будет запуск двух виртуальных машин, предоставление им одного и того же IP-адреса, а также разных MAC-адресов и просмотр того, что происходит - вы заметите, что несколько раз VM1 получит пакеты, а в других случаях VM2 получит пакеты - в зависимости от обновления кеша ARP).

Я чувствую, что, запустив два приложения на одном и том же <op-address>:<port>, вы хотите достичь какой-то балансировки нагрузки. Для этого вы можете запускать приложения на разных портах и ​​записывать правила таблицы IP, чтобы раздвоить трафик между ними.

Также см. ответ @user6169806.