web-dev-qa-db-fra.com

Deux applications peuvent-elles écouter le même port?

Deux applications d'une même machine peuvent-elles être liées au même port et à la même adresse IP? Pour aller un peu plus loin, une application peut-elle écouter les demandes provenant d'une certaine adresse IP et l'autre sur une autre adresse IP distante? Je sais que je peux avoir une application qui démarre deux threads (ou fourches) pour avoir un comportement similaire, mais deux applications n'ayant rien en commun peuvent-elles faire la même chose?

257
nadiv

La réponse varie en fonction du système d'exploitation considéré. En général cependant:

Pour TCP, non. Vous ne pouvez avoir qu'une seule application écoutant le même port à la fois. Maintenant, si vous aviez 2 cartes réseau, vous pourriez avoir une application à écouter sur la première IP et la seconde sur la deuxième IP en utilisant le même numéro de port.

Pour UDP (Multicasts), plusieurs applications peuvent s'abonner au même port.

Edit: Depuis le noyau Linux 3.9 et versions ultérieures, la prise en charge de plusieurs applications écoutant le même port a été ajoutée à l’aide de l’option SO_REUSEPORT. Plus d'informations sont disponibles sur cet article de lwn.net.

229
Chris Dail

Oui (pour TCP), vous pouvez faire en sorte que deux programmes écoutent sur le même socket, s’ils sont conçus pour le faire. Lorsque le socket est créé par le premier programme, assurez-vous que l'option SO_REUSEADDR est définie sur le socket avant de bind(). Cependant, cela peut ne pas être ce que vous voulez. Cela signifie qu'une connexion entrante TCP sera dirigée vers n des programmes, pas les deux, afin de ne pas dupliquer la connexion, cela permet simplement à deux programmes de gérer le service entrant. demande. Par exemple, les serveurs Web auront plusieurs processus qui seront tous à l'écoute sur le port 80 et le système d'exploitation enverra une nouvelle connexion au processus qui est prêt à accepter de nouvelles connexions.

SO_REUSEADDR

Autorise les autres sockets à bind() sur ce port, sauf si un socket d'écoute actif est déjà lié au port. Cela vous permet de contourner les messages d'erreur "Adresse déjà utilisée" lorsque vous essayez de redémarrer votre serveur après un blocage.

113
JNewton

En principe non.

Ce n'est pas écrit dans la pierre; mais c'est la façon dont toutes les API sont écrites: l'application ouvre un port, y obtient un handle, et le système d'exploitation le notifie (via ce handle) lorsqu'une connexion client (ou un paquet dans le cas UDP) arrive.

Si le système d'exploitation permettait à deux applications d'ouvrir le même port, comment pourrait-il savoir laquelle notifier?

Mais ... il y a des façons de le contourner:

  1. En tant que Jed noté , vous pouvez écrire un processus "maître", qui serait le seul à réellement écouter le port et notifier les autres, en utilisant toute logique voulant qu’il sépare les demandes des clients.
    • Sous Linux et BSD (au moins), vous pouvez configurer des règles de "remappage" qui redirigent les paquets du port "visible" vers différents ports (où les applications sont à l'écoute), en fonction de tous les critères liés au réseau (réseau d'origine, formes simples d’équilibrage de charge).
47
Javier

Oui.

  1. Plusieurs connecteurs TCP, reliés au même port, peuvent coexister, à condition qu'ils soient tous liés à des adresses IP locales différentes. Les clients peuvent se connecter à celui dont ils ont besoin. Ceci exclut 0.0.0.0 (INADDR_ANY).

  2. Plusieurs sockets acceptés peuvent coexister, tous acceptés à partir du même socket d'écoute, affichant tous le même numéro de port local que le socket d'écoute.

  3. Plusieurs sockets UDP, tous liés au même port, peuvent tous coexister à condition que la condition soit identique à celle de (1) ou que l'option SO_REUSEADDR ait été définie avant la liaison.

  4. Les ports TCP et UDP occupant différents espaces de noms, l’utilisation d’un port pour TCP n’empêche pas son utilisation pour UDP, et et inversement.

Référence: Stevens & Wright, TCP/IP illustré, volume II.

46
user207421

Oui sans aucun doute . Autant que je me souvienne À partir de la version 3.9 du noyau (incertain sur la version), le support pour le SO_REUSEPORT a été introduit. SO_RESUEPORT autorise la liaison au même port et à la même adresse, tant que le premier serveur définit cette option avant de lier son socket.

Cela fonctionne à la fois TCP et UDP. Reportez-vous au lien pour plus de détails: SO_REUSEPORT

Note : La réponse acceptée n'est plus vraie selon mon opinion.

24
piyush

Non. Une seule application peut se lier à un port à la fois, et le comportement si la liaison est forcée est indéterminé.

Avec les sockets multicast - qui sonnent loin de ce que vous voulez -, plusieurs applications peuvent se lier à un port tant que SO_REUSEADDR est défini dans les options de chaque socket.

Pour ce faire, vous pouvez écrire un processus "maître" qui accepte et traite toutes les connexions, puis les transfère à vos deux applications qui doivent écouter sur le même port. C’est cette approche que les serveurs Web et autres adoptent, car de nombreux processus doivent écouter 80.

Au-delà de cela, nous entrons dans les détails - vous avez balisé TCP et UDP, qui est-ce? Aussi, quelle plate-forme?

18
Jed Smith

Vous pouvez avoir une application qui écoute sur un port pour une interface réseau. Par conséquent, vous pourriez avoir:

  1. httpd écoute sur une interface accessible à distance, par exemple. 192.168.1.1:80
  2. un autre démon écoutant sur 127.0.0.1:80

Un exemple de cas d'utilisation pourrait consister à utiliser httpd en tant qu'équilibreur de charge ou proxy.

3
SummerBreeze

Une autre méthode consiste à utiliser un programme en écoute sur un port qui analyse le type de trafic (ssh, https, etc.) qu’il redirige en interne vers un autre port sur lequel le "vrai" service est à l’écoute.

Par exemple, pour Linux, sslh: https://github.com/yrutschle/sslh

3
Mitchbcn

Lorsque vous créez une connexion TCP, vous devez vous connecter à une adresse TCP spécifique, qui est une combinaison d'une adresse IP (v4 ou v6, selon le protocole utilisé). ) et un port.

Lorsqu'un serveur écoute les connexions, il peut informer le noyau qu'il souhaite écouter une adresse IP et un port spécifiques, c'est-à-dire une adresse TCP, ou sur le même port sur chacune des adresses IP de l'hôte. (généralement spécifié avec l'adresse IP 0.0.0.0), qui écoute effectivement de nombreuses "adresses TCP" différentes (par exemple, 192.168.1.10:8000, 127.0.0.1:8000, etc.)

Non, vous ne pouvez pas avoir deux applications qui écoutent la même "adresse TCP", car quand un message arrive, comment le noyau pourrait-il savoir à quelle application donner le message?

Cependant, dans la plupart des systèmes d’exploitation, vous pouvez configurer plusieurs adresses IP sur une seule interface (par exemple, si vous avez 192.168.1.10 sur une interface, vous pouvez également configurer 192.168.1.11 si personne d’autre du réseau utilise), et dans ces cas, vous pouvez avoir des applications distinctes écoutant le port 8000 sur chacune de ces deux adresses IP.

2
Curt J. Sampson

Si au moins une des adresses IP distantes est déjà connue, statique et dédiée à la communication avec une seule de vos applications, vous pouvez utiliser la règle iptables (table nat, chaîne PREROUTING) pour rediriger le trafic entrant de cette adresse vers le port local "partagé" vers tout autre port sur lequel l'application appropriée écoute réellement.

2
Stemar

Oui.

De cet article:
https://lwn.net/Articles/542629/

La nouvelle option de socket permet à plusieurs sockets sur le même hôte de se lier au même port

1
user6169806

Oui et non. Une seule application peut écouter activement sur un port. Mais cette application peut léguer sa connexion à un autre processus. Vous pouvez donc avoir plusieurs processus travaillant sur le même port.

1
rajesh

Vous pouvez faire en sorte que deux applications écoutent le même port sur la même interface réseau.

Il ne peut exister qu'un seul connecteur d'écoute pour l'interface réseau et le port spécifiés, mais ce connecteur peut être partagé entre plusieurs applications.

Si vous avez un socket en écoute dans un processus d'application et que vous fork, le socket sera hérité, donc techniquement, il y aura maintenant deux processus en train d'écouter le même port.

0
warvariuc

J'ai essayé ce qui suit avec socat:

socat TCP-L:8080,fork,reuseaddr -

Et même si je n'ai pas établi de connexion à la prise, je ne peux pas écouter deux fois sur le même port, malgré l'option reuseaddr.

Je reçois ce message (auquel je m'attendais avant):

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

Juste pour partager ce que @jnewton a mentionné. J'ai démarré un nginx et un processus Tomcat intégré sur mon mac. Je peux voir les deux processus en cours d'exécution à 8080.

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

Si par applications, vous entendez plusieurs processus, alors oui mais généralement non. Par exemple, le serveur Apache exécute plusieurs processus sur le même port (généralement 80). Pour ce faire, un des processus doit être lié au port, puis utilisé pour effectuer des transferts vers différents processus acceptant des connexions.

0
nitinsh99