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?
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.
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.
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:
Oui.
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
).
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.
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.
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.
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.
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?
Vous pouvez avoir une application qui écoute sur un port pour une interface réseau. Par conséquent, vous pourriez avoir:
httpd
écoute sur une interface accessible à distance, par exemple. 192.168.1.1:80
127.0.0.1:80
Un exemple de cas d'utilisation pourrait consister à utiliser httpd
en tant qu'équilibreur de charge ou proxy.
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
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.
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.
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
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.
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.
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
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
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.