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

Deux applications sur la même machine peuvent-elles être liées au même port et à la même adresse IP? En allant plus loin, une application peut-elle écouter les demandes provenant d’une certaine adresse IP et l’autre vers une autre adresse IP distante? Je sais que je peux avoir une application qui commence par deux threads (ou des forks) pour avoir un comportement similaire, mais deux applications qui n’ont rien en commun peuvent-elles faire la même chose?

Pour TCP, non. Vous ne pouvez avoir qu’une seule application à l’écoute sur 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 deuxième 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.

Oui (pour TCP), vous pouvez faire écouter deux programmes sur le même socket, si les programmes 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 la bind() . Cependant, cela peut ne pas être ce que vous voulez. Ce que cela fait est qu’une connexion TCP entrante sera dirigée vers l’ un des programmes, pas les deux, de sorte qu’elle ne duplique pas la connexion, elle permet simplement à deux programmes de traiter la demande entrante. Par exemple, les serveurs Web auront plusieurs processus écoutant tous sur le port 80 et le S / S envoie une nouvelle connexion au processus qui est prêt à accepter de nouvelles connexions.

 SO_REUSEADDR 

Permet aux autres sockets de bind() à ce port, sauf s’il existe déjà un socket d’écoute actif 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 en pierre; mais c’est la façon dont toutes les API sont écrites: l’application ouvre un port, obtient un handle vers lui, 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 autorisait deux applications à ouvrir le même port, comment pourrait-il savoir lequel informer?

Mais … il y a des solutions:

  1. Comme Jed l’a noté , vous pouvez écrire un processus «maître», qui serait le seul à réellement écouter le port et avertir les autres, en utilisant la logique qu’il souhaite séparer des requêtes client.
    • Sous Linux et BSD (au moins), vous pouvez définir des règles de «remappage» qui redirigent les paquets du port «visible» vers des ports différents (où les applications sont à l’écoute), en fonction de critères formes simples d’équilibrage de charge).

Oui.

  1. Plusieurs sockets TCP d’écoute, tous lié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 depuis le 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 qu’ils aient la même condition qu’en (1) ou qu’ils aient tous SO_REUSEADDR option SO_REUSEADDR avant la liaison.

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

Référence: Stevens & Wright, TCP / IP Illustrated, Volume II.

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 ne ressemblent à rien 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.

Vous pouvez accomplir cela en écrivant un processus “maître”, qui accepte et traite toutes les connexions, puis les transmet à vos deux applications qui doivent écouter sur le même port. C’est l’approche que prennent les serveurs Web et autres, car de nombreux processus doivent écouter 80.

Au-delà de cela, nous entrons dans les détails – vous avez tagué TCP et UDP, c’est quoi? Aussi, quelle plate-forme?

Oui définitivement Pour autant que je me souvienne De la version 3.9 du kernel (pas sûr de la version), la prise en charge de SO_REUSEPORT été introduite. SO_RESUEPORT permet de lier exactement le même port et l’adresse, à condition que le premier serveur définisse cette option avant de lier son socket.

Cela fonctionne pour TCP et UDP . Référez-vous au lien pour plus de détails: SO_REUSEPORT

Note : La réponse acceptée n’est plus valable selon mon opinion.

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 en écoute sur 127.0.0.1:80

Exemple d’utilisation: utiliser httpd comme équilibreur de charge ou proxy.

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

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

Si au moins une des adresses IP distantes est déjà connue, statique et dédiée pour ne parler qu’à l’une de vos applications, vous pouvez utiliser la règle iptables (table nat, chaîne PREROUTING) pour redirect le trafic entrant de cette adresse vers le port local «partagé». tout autre port où l’application appropriée écoute réellement.

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

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 connecter au même port

Lorsque vous créez une connexion TCP, vous demandez de vous connecter à une adresse TCP spécifique, qui est une combinaison d’une adresse IP (v4 ou v6, selon le protocole que vous utilisez) et d’un port.

Lorsqu’un serveur écoute les connexions, il peut informer le kernel qu’il souhaite écouter une adresse IP et un port spécifiques, c’est-à-dire une adresse IP ou sur toutes les adresses IP des hôtes, chacun sur un port spécifique, ce qui est efficace. écouter sur beaucoup de différentes “adresses TCP” (par exemple, 192.168.1.10:8000, 127.0.0.1:8000, etc.)

Non, vous ne pouvez pas avoir deux applications écoutant sur la même “adresse TCP”, car quand un message arrive, comment le kernel sait-il à 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 sur le réseau ne l’utilise). , et dans ces cas, vous pourriez avoir des applications séparées écoutant sur le port 8000 sur chacune de ces deux adresses IP.

Si par applications, vous voulez dire 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). En définissant l’un des processus à lier au port, il utilise ce processus pour effectuer des transferts vers différents processus qui acceptent les connexions.

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

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

Si vous avez un socket d’écoute dans un processus d’application et que vous fork ce processus, le socket sera hérité, donc techniquement, il y aura maintenant deux processus qui écoutent 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 socket, 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 

Réponse courte:

Aller par la réponse donnée ici . Vous pouvez avoir deux applications qui écoutent sur la même adresse IP et le même numéro de port, aussi longtemps qu’un port est un port UDP, tandis que l’autre est un port TCP.

Explication:

Le concept de port est pertinent sur la couche de transport de la stack TCP / IP. Ainsi, tant que vous utilisez différents protocoles de couche de transport de la stack, vous pouvez avoir plusieurs processus à l’écoute sur la même : combinaison.

Le doute est que si deux applications s’exécutent sur la même combinaison : , comment un client s’exécutant sur une machine distante fera-t-il la distinction entre les deux? Si vous regardez l’en-tête de paquet de la couche IP ( https://en.wikipedia.org/wiki/IPv4#Header ), vous verrez que les bits 72 à 79 sont utilisés pour définir le protocole, c’est ainsi que la distinction peut être faite.

Si toutefois vous voulez avoir deux applications sur la même combinaison TCP : , alors la réponse est non (un exercice intéressant sera de lancer deux machines virtuelles, leur donner la même adresse IP, mais des adresses MAC différentes, et voir ce qui se passe – vous remarquerez que parfois VM1 va recevoir des paquets, et d’autres fois VM2 obtiendra des paquets – en fonction de l’actualisation du cache ARP).

Je pense qu’en faisant tourner deux applications sur la même : vous voulez réaliser un équilibrage de charge. Pour cela, vous pouvez exécuter les applications sur différents ports et écrire des règles de table IP pour diviser le trafic entre elles.

Voir aussi la réponse de @ user6169806.