web-dev-qa-db-fra.com

Comment plusieurs clients peuvent-ils se connecter simultanément à un port, disons 80, sur un serveur?

Je comprends les bases du fonctionnement des ports. Cependant, ce que je ne comprends pas, c'est comment plusieurs clients peuvent se connecter simultanément au dit port 80. Je sais que chaque client possède un port unique (pour leur machine). Le serveur répond-il depuis un port disponible au client et indique-t-il simplement que la réponse provenait de 80? Comment cela marche-t-il?

373
IamIC

Tout d'abord, un "port" n'est qu'un nombre. Tout ce qu'une "connexion à un port" représente réellement est un paquet dont le numéro est spécifié dans son champ d'en-tête "port de destination".

Vous avez maintenant deux réponses à votre question, une pour les protocoles avec état et une pour les protocoles sans état.

Pour un protocole sans état (c'est-à-dire UDP), il n'y a pas de problème car les "connexions" n'existent pas - plusieurs personnes peuvent envoyer des paquets sur le même port et leurs paquets arriveront dans n'importe quelle séquence. Personne n'est jamais dans l'état "connecté".

Pour un protocole avec état (tel que TCP), une connexion est identifiée par un 4-Tuple composé de ports source et de destination et d'adresses IP source et de destination. Ainsi, si deux machines différentes se connectent au même port sur une troisième machine, il existe deux connexions distinctes car les adresses IP source diffèrent. Si la même machine (ou deux derrière NAT ou partageant la même adresse IP) se connecte deux fois à une même extrémité distante, les connexions sont différenciées par le port source (qui est généralement un port aléatoire numéroté en haut).

Simplement, si je me connecte deux fois au même serveur Web à partir de mon client, les deux connexions auront des ports source différents de mon point de vue et des ports de destination du serveur Web. Il n’ya donc aucune ambiguïté, même si les deux connexions ont les mêmes adresses IP source et de destination.

Les ports sont un moyen de multiplexer adresses IP afin que différentes applications puissent écouter sur la même paire adresse IP/protocole. À moins qu'une application ne définisse son propre protocole de niveau supérieur, il n'y a aucun moyen de multiplexer un port. Si deux connexions utilisant le même protocole ont simultanément des adresses IP de source et de destination identiques et des ports de source et de destination identiques, il doit s'agir de la même connexion.

435
Borealid

Important:

Je suis désolé de dire que la réponse de "Borealid" est imprécise et quelque peu incorrecte. En premier lieu, il n'y a aucun lien avec l'étatfulness ou l'apatridie pour répondre à cette question, et le plus important est que la définition du Tuple pour un socket est incorrecte.

Commencez par rappeler ci-dessous deux règles:

  1. Clé primaire d'un socket: Un socket est identifié par {SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL} pas par {SRC-IP, SRC-PORT, DEST-IP, DEST-PORT} - Le protocole est une partie importante de la définition d'un socket.

  2. Système OS et mappage de sockets: un processus peut être associé à plusieurs sockets (peut ouvrir/écouter), ce qui peut sembler évident à de nombreux lecteurs.

Exemple 1: Deux clients se connectant au même port de serveur signifient: socket1 {SRC-A, 100, DEST-X,80, TCP} et socket2{SRC-B, 100, DEST-X,80, TCP}. Cela signifie que l'hôte A se connecte au port 80 du serveur X et qu'un autre hôte B se connecte également au même serveur X au même port 80. Désormais, la manière dont le serveur gère ces deux sockets dépend du type de serveur: thread unique ou multi-thread expliquer cela plus tard). L'important est qu'un serveur puisse écouter plusieurs sockets simultanément.

Pour répondre à la question initiale du message:

Indépendamment des protocoles sans état ou sans état, deux clients peuvent se connecter au même port de serveur car pour chaque client, nous pouvons attribuer un socket différent (car l'adresse IP du client sera certainement différente). Un même client peut également disposer de deux sockets se connectant au même port de serveur, car ces sockets diffèrent de SRC-PORT. En toute honnêteté, "Borealid" a essentiellement mentionné la même réponse correcte, mais la référence à "sans état/complet" était plutôt inutile/source de confusion.

Pour répondre à la deuxième partie de la question sur la façon dont un serveur sait à quel socket répondre. Tout d’abord, comprenez que pour un processus serveur unique qui écoute le même port, il peut y avoir plusieurs sockets (pouvant provenir du même client ou de clients différents). Maintenant, tant qu'un serveur sait quelle requête est associée à quel socket, il peut toujours répondre au client approprié en utilisant le même socket. Ainsi, un serveur n'a jamais besoin d'ouvrir un autre port sur son propre noeud que celui d'origine sur lequel le client a initialement essayé de se connecter. bind relier. Si un serveur alloue des ports de serveur différents après la connexion d'un socket, alors, à mon avis, le serveur gaspille ses ressources et il doit avoir besoin du client bind reconnectez-vous au nouveau port attribué.

Un peu plus pour être complet:

Exemple 2: C'est une question très intéressante: les deux processus différents d'un serveur peuvent-ils écouter le même port. Si vous ne considérez pas le protocole comme l'un des paramètres définissant socket, la réponse est non. Au départ, il en est ainsi parce que nous pouvons dire que, dans ce cas, un seul client essayant de se connecter à un port de serveur ne disposera d'aucun mécanisme pour mentionner lequel des deux processus d'écoute le client a l'intention. C'est le même thème affirmé par la règle (2). Cependant, c'est une réponse FAUX, car "protocole" fait également partie de la définition du socket. Ainsi, deux processus d'un même noeud ne peuvent écouter le même port que s'ils utilisent un protocole différent. Par exemple, deux clients indépendants (par exemple, un utilise TCP et un autre utilise UDP) peut bind connectez-vous et communiquez au même nœud de serveur et au même port, mais ils doivent être desservis par deux processus de serveur différents.

Types de serveurs - single & multiple:

Lorsque les processus d'un serveur écoutent un port, cela signifie que plusieurs sockets peuvent se connecter et communiquer simultanément avec le même processus serveur. Si un serveur utilise un seul processus enfant pour desservir tous les sockets, il s'appelle single-process/threaded et si le serveur utilise plusieurs sous-processus pour desservir chaque socket par un sous-processus, il est appelé multi-processus. serveur de processus/threadé. Notez que quel que soit le type de serveur, un serveur peut/doit toujours utiliser le même socket initial pour répondre (il n'est pas nécessaire d'allouer un autre port de serveur).

Suggéré Livres et reste des deux volumes si vous le pouvez.

Note sur le processus parent/enfant (en réponse à la requête/au commentaire de 'Ioan Alexandru Cucu')

Partout où j'ai mentionné un concept en relation avec deux processus, dites A et B, considérez qu'ils ne sont pas liés par une relation parent-enfant. Les systèmes d'exploitation (en particulier UNIX) permettent par leur conception à un processus enfant d'hériter tous les descripteurs de fichiers (FD) des parents. Ainsi, tous les sockets (sous UNIX comme OS font également partie de FD) qu’un processus A en écoute peut être écouté par de nombreux autres processus A1, A2, .. tant qu’ils sont liés par une relation parent-enfant à A. Mais un processus indépendant B (c'est-à-dire n'ayant pas de relation parent-enfant avec A) ne peut pas écouter le même socket. En outre, notez également que cette règle qui interdit à deux processus indépendants d'écouter le même socket repose sur un système d'exploitation (ou ses bibliothèques réseau) et de loin, elle est respectée par la plupart des systèmes d'exploitation. Cependant, on peut créer son propre système d'exploitation qui peut très bien violer ces restrictions.

341
KGhatak

Écoute TCP/HTTP sur les ports: Comment plusieurs utilisateurs peuvent-ils partager le même port?

Alors, que se passe-t-il lorsqu'un serveur écoute les connexions entrantes sur un port TCP? Par exemple, supposons que vous avez un serveur Web sur le port 80. Supposons que votre ordinateur a l'adresse IP publique de 24.14.181.229 et que la personne qui tente de se connecter à vous a l'adresse IP 10.1.2.3. Cette personne peut se connecter à vous en ouvrant un socket TCP vers 24.14.181.229:80. Assez simple.

Intuitivement (et à tort), la plupart des gens supposent que cela ressemble à ceci:

    Local Computer    | Remote Computer
    --------------------------------
    <local_ip>:80     | <foreign_ip>:80

    ^^ not actually what happens, but this is the conceptual model a lot of people have in mind.

Ceci est intuitif, car du point de vue du client, il a une adresse IP et se connecte à un serveur à l'adresse IP: PORT. Puisque le client se connecte au port 80, son port doit être également 80? C'est une chose sensée à penser, mais en réalité pas ce qui se passe. Si cela devait être correct, nous ne pourrions servir qu'un seul utilisateur par adresse IP étrangère. Une fois qu'un ordinateur distant est connecté, il connecte les ports 80 à 80 et personne d'autre ne peut se connecter.

Trois choses doivent être comprises:

1.) Sur un serveur, un processus écoute sur un port. Une fois qu'il est connecté, il passe à un autre thread. La communication ne cache jamais le port d'écoute.

2.) Les connexions sont identifiées de manière unique par le système d’exploitation par le 5-Tuple suivant: (IP local, port local, IP distant, port distant, protocole). Si l'un des éléments du tuple est différent, il s'agit d'une connexion totalement indépendante.

3.) Lorsqu'un client se connecte à un serveur, il choisit un port source aléatoire inutilisé . De cette façon, un seul client peut avoir jusqu'à 64 000 connexions au serveur pour le même port de destination.

Donc, c'est vraiment ce qui est créé lorsqu'un client se connecte à un serveur:

    Local Computer   | Remote Computer           | Role
    -----------------------------------------------------------
    0.0.0.0:80       | <none>                    | LISTENING
    127.0.0.1:80     | 10.1.2.3:<random_port>    | ESTABLISHED

Regarder ce qui se passe réellement

Tout d’abord, utilisons netstat pour voir ce qui se passe sur cet ordinateur. Nous allons utiliser le port 500 au lieu de 80 (parce que tout un tas de choses se passent sur le port 80 car c'est un port commun, mais sur le plan fonctionnel, cela ne fait aucune différence).

    netstat -atnp | grep -i ":500 "

Comme prévu, la sortie est vide. Maintenant, démarrons un serveur web:

    Sudo python3 -m http.server 500

Maintenant, voici le résultat de l'exécution de netstat à nouveau:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State  
    tcp        0      0 0.0.0.0:500             0.0.0.0:*               LISTEN      - 

Il existe donc à présent un processus à l'écoute active (State: LISTEN) sur le port 500. L'adresse locale est 0.0.0.0, qui correspond au code "écoute pour tous". Une erreur facile à faire est d'écouter l'adresse 127.0.0.1, qui n'acceptera que les connexions de l'ordinateur actuel. Donc, ce n'est pas une connexion, cela signifie simplement qu'un processus a demandé à bind () de porter l'adresse IP, et que ce processus est responsable du traitement de toutes les connexions à ce port. Cela laisse à penser qu'il ne peut y avoir qu'un seul processus par ordinateur qui écoute sur un port (il existe des moyens de contourner ce problème en utilisant le multiplexage, mais le sujet est beaucoup plus compliqué). Si un serveur Web écoute sur le port 80, il ne peut pas partager ce port avec d'autres serveurs Web.

Alors maintenant, connectons un utilisateur à notre machine:

    quicknet -m tcp -t localhost:500 -p Test payload.

C’est un script simple ( https://github.com/grokit/dcore/tree/master/apps/quicknet ) qui ouvre un socket TCP, envoie la charge utile (" Test payload. "Dans ce cas), attend quelques secondes et se déconnecte. Faire de nouveau netstat pendant que cela se produit affiche les éléments suivants:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State  
    tcp        0      0 0.0.0.0:500             0.0.0.0:*               LISTEN      -
    tcp        0      0 192.168.1.10:500        192.168.1.13:54240      ESTABLISHED -

Si vous vous connectez à un autre client et effectuez à nouveau netstat, vous verrez ce qui suit:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State  
    tcp        0      0 0.0.0.0:500             0.0.0.0:*               LISTEN      -
    tcp        0      0 192.168.1.10:500        192.168.1.13:26813      ESTABLISHED -

... c'est-à-dire que le client a utilisé un autre port aléatoire pour la connexion. Donc, il n'y a jamais de confusion entre les adresses IP.

172
N0thing

Normalement, pour chaque client se connectant, le serveur crée un processus enfant communiquant avec le client (TCP). Le serveur parent transmet au processus enfant un socket établi qui communique avec le client.

Lorsque vous envoyez les données à un socket de votre serveur enfant via un socket, la pile TCP du système d'exploitation crée un paquet qui retourne au client et définit le "port" à 80.

25
m1tk4

Plusieurs clients peuvent se connecter au même port (par exemple 80) sur le serveur car, côté serveur, après avoir créé une socket et binding (configuration de l'adresse IP locale et du port) listen est appelé sur le socket qui demande à l'OS d'accepter connexions entrantes.

Lorsqu'un client tente de se connecter au serveur sur le port 80, l'appel accept est appelé sur le socket du serveur. Cela crée un nouveau socket pour le client essayant de se connecter et de nouveaux sockets seront créés pour les clients suivants utilisant le même port 80.

Les mots en italique sont des appels système.

Ref

http://www.scs.stanford.edu/07wi-cs244b/refs/net2.pdf

4
pumpkin_cat