La poignée de main TCP 3-way fonctionne comme ceci:
Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server
Pourquoi pas juste ça?
Client ------SYN-----> Server
Client <-----ACK------ Server
La poignée de main TCP 3-way fonctionne comme ceci:
Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server
Pourquoi pas juste ça?
Client ------SYN-----> Server
Client <-----ACK------ Server
Réponses:
Décomposer la poignée de main dans ce qu'il fait vraiment.
Dans TCP, les deux parties gardent une trace de ce qu’elles ont envoyé en utilisant un numéro de séquence. Effectivement, il finit par être un nombre d'octets en cours de tout ce qui a été envoyé. La partie destinataire peut utiliser le numéro de séquence du locuteur opposé pour accuser réception de ce qu'elle a reçu.
Mais le numéro de séquence ne commence pas à 0. Il commence par le numéro de séquence initial (ISN), qui est une valeur choisie au hasard. Et comme TCP est une communication bidirectionnelle, les deux parties peuvent "parler" et doivent donc générer de manière aléatoire un ISN en tant que numéro de séquence de départ. Ce qui à son tour signifie que les deux parties doivent informer l’autre partie de leur numéro ISN de départ.
Donc, vous vous retrouvez avec cette séquence d'événements pour le début d'une conversation TCP entre Alice et Bob:
Alice ---> Bob SYNchronize with my Initial Sequence Number of X
Alice <--- Bob I received your syn, I ACKnowledge that I am ready for [X+1]
Alice <--- Bob SYNchronize with my Initial Sequence Number of Y
Alice ---> Bob I received your syn, I ACKnowledge that I am ready for [Y+1]
Avis, quatre événements se produisent:
En réalité cependant, les deux événements du milieu (n ° 2 et n ° 3) se produisent dans le même paquet. Ce qui fait qu'un paquet est SYN
ou ACK
est simplement un indicateur binaire activé ou désactivé à l'intérieur de chaque en- tête TCP , rien n'empêche donc l'activation de ces deux indicateurs sur le même paquet. Ainsi, la poignée de main à trois voies finit par être:
Bob <--- Alice SYN
Bob ---> Alice SYN ACK
Bob <--- Alice ACK
Notez les deux instances de "SYN" et "ACK", une de chaque, dans les deux sens.
Donc, pour revenir à votre question, pourquoi ne pas simplement utiliser une poignée de main bidirectionnelle? La réponse courte est qu’une poignée de main dans les deux sens ne permettrait à une partie d’établir un ISN et à l’autre de le reconnaître. Ce qui signifie qu'une seule partie peut envoyer des données.
Mais TCP est un protocole de communication bidirectionnel, ce qui signifie que chaque extrémité devrait pouvoir envoyer des données de manière fiable. Les deux parties doivent établir un numéro ISN, et les deux parties doivent reconnaître le numéro ISN de l'autre.
Donc, en réalité, ce que vous avez est exactement votre description de la poignée de main bidirectionnelle, mais dans chaque direction . Par conséquent, quatre événements se produisent. Et encore une fois, les deux drapeaux du milieu apparaissent dans le même paquet. En tant que tel, trois paquets sont impliqués dans un processus d'initiation de connexion TCP complet.
La poignée de main à trois voies est nécessaire parce que les deux parties doivent syn chronize leurs numéros de séquence de segments utilisés au cours de leur transmission. A cet effet , chacune d'entre elles envoie (tour à tour) un segment SYN avec un numéro de séquence pour une valeur aléatoire n , qui est ensuite ack nowledged par l'autre partie par l' intermédiaire d' un segment d'accusé de réception avec un numéro de séquence à n + 1 .
Eddie
commentaire de à sa réponse.
Pour que la connexion fonctionne, chaque côté doit vérifier qu'il peut envoyer des paquets à l'autre côté. Le seul moyen de vous assurer que vous avez reçu un paquet de l'autre côté est de recevoir d'eux un paquet qui, par définition, n'aurait pas été envoyé sans le paquet que vous avez envoyé . Pour ce faire, TCP utilise essentiellement deux types de messages: SYN (pour demander la preuve que ce paquet a bien traversé) et ACK (qui n'est envoyé qu'après qu'un SYN a réussi, pour prouver que le SYN est bien passé). Il y a en fait un troisième type de message, mais nous y reviendrons dans un instant.
Avant que la connexion ne commence, aucune des deux parties ne sait vraiment quoi que ce soit de l'autre. Le client envoie un paquet SYN au serveur afin de demander la preuve que ses messages peuvent passer . Cela ne dit rien à personne, mais c'est la première étape de la poignée de main.
Si le SYN réussit, le serveur sait que le client peut lui envoyer des paquets car, eh bien, cela vient de se produire. Mais cela ne prouve pas que le serveur peut renvoyer des paquets: les clients peuvent envoyer des SYN pour de nombreuses raisons . Le serveur doit donc renvoyer deux messages au client: un ACK (pour prouver que le SYN a réussi) et un SYN (pour demander un ACK). TCP combine ces deux messages en un seul message -a SYN-ACK, si vous voulez, pour réduire le trafic réseau. C'est la deuxième étape de la poignée de main.
Comme un SYN-ACK est un ACK, le client sait maintenant avec certitude qu'il peut envoyer des paquets au serveur. Et puisqu'un SYN-ACK est un SYN, il sait également que le serveur veut une preuve que ce message est passé. Donc, il renvoie un ACK: juste un ACK ordinaire, car il n'a plus besoin de preuve que ses paquets peuvent passer. Il s’agit de la dernière étape de la négociation: le client sait maintenant que les paquets peuvent aller dans les deux sens, et que le serveur est sur le point de comprendre cela (car il sait que le ACK passera).
Une fois que cet ACK est passé, le serveur sait maintenant qu'il peut envoyer des paquets au client . Il sait également que le client le sait, ce qui lui permet de commencer immédiatement à envoyer des données. La poignée de main est terminée. Nous avons un bon canal.
Eh bien, à proprement parler, nous ne pouvons pas être sûrs d' avoir un bon canal . Le fait que cette séquence de paquets soit passée ne garantit pas strictement que d’autres le feront. Nous ne pouvons pas prouver cela sans envoyer un nombre infini de SYN et ACK, et rien d'autre ne serait jamais fait. Ce n'est donc pas vraiment une option pratique. Mais dans la pratique, trois étapes s'avèrent suffisantes pour la plupart des objectifs .
En fait, une poignée de main à trois voies n'est pas le seul moyen d'établir une connexion TCP. L'échange SYN simultané est également autorisé: http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh-4.htm
Cela pourrait être vu comme une sorte de double poignée de main à double sens.
La connexion TCP est bidirectionnelle. Cela signifie que c'est en fait une paire de connexions à sens unique. L'initiateur envoie SYN, le répondeur envoie ACK: une connexion simplex commence. "Ensuite", le répondeur envoie SYN, l'initiateur envoie ACK: une autre connexion simplex commence. Deux connexions simplex forment une session TCP duplex, d'accord? Donc logiquement, il y a quatre étapes. mais comme les drapeaux SYN et ACK sont des "champs" différents de l'en-tête TCP, ils peuvent être configurés simultanément. Les deuxième et troisième étapes (sur les quatre) sont combinées, de sorte qu'il existe techniquement trois échanges de paquets. Chaque connexion simplex (demi) utilise un échange bidirectionnel, comme vous l'avez proposé.
Si le serveur et le client veulent créer une connexion, ils doivent confirmer quatre choses:
Le client doit confirmer qu'il peut recevoir le paquet du serveur
Le client doit confirmer une chose: le serveur peut recevoir un paquet du client
Après Client ------SYN-----> Server
, la règle 1 est confirmée.
Après Client <---ACK/SYN---- Server
, les règles 2 et 3 sont confirmées.
Donc, il faut un troisième paquet pour confirmer la règle 4.
Ce n'est pas nécessaire du tout. Il est évident qu'un message court ne doit nécessiter qu'un seul paquet vers le serveur, qui comprend le message start +, et un paquet l'accusé de réception.
Les réponses précédentes décrivent simplement le système sans discuter du besoin de numéros de séquence aléatoires, etc. La question initiale portait sur la conception du protocole TCP lui-même - si vous utilisez le protocole TCP, vous avez évidemment besoin de trois messages, car il s'agit du protocole. Mais pourquoi TCP a-t-il été conçu de cette manière?
Je crois que l’idée de départ était qu’il n’y avait pas de distinction entre les clients et les serveurs. Tous deux connaissaient les ports de l'autre d'une manière bidirectionnelle et l'un ou l'autre pouvait démarrer la conversation. Et cela nécessitait Syns etc.
Mais ce n'est pas, bien sûr, comment il est utilisé aujourd'hui. Le serveur écoute sur un port bien connu et accepte et "accepte", le numéro de port du client est éphémère. Je ne pense même pas qu'il soit possible pour un serveur en attente d'acceptation d'envoyer une requête à un autre sur le même numéro de port client dans les systèmes d'exploitation normaux.
(Notez qu'il s'agit d'une connexion bidirectionnelle, ce qui n'est jamais fait aujourd'hui. C'est très différent d'envoyer des messages bidirectionnels via une connexion une fois établie.)
Pour contourner l'inefficacité TCP, nous utilisons des protocoles tels que HTTP 1.1, qui peuvent réutiliser la même connexion pour plusieurs requêtes et éviter ainsi la négociation TCP qui n'était pas nécessaire en premier lieu.
Mais Http 1.1 est relativement nouveau. Et SSL / TLS avait besoin d’un moyen de réutiliser une session depuis le début en raison du coût des algorithmes PKI. Donc, ce protocole inclut son propre mécanisme de réutilisation de session qui s’exécute sur HTTP 1.1 qui s’exécute sur TCP.
Tel est le chemin avec le logiciel. Fudges sur kludges qui, une fois combinés, produisent un résultat acceptable.
Après avoir lu la réponse d'Eddie (acceptée comme correcte), il reste à savoir pourquoi le premier hôte ne peut pas affecter les deux numéros ISN avec des nombres aléatoires et le 2e accepte simplement de l'accepter. La vraie raison d'utiliser la poignée de main à 3 voies est d'éviter les demi-connexions . Scénario de demi-connexion en négociation bidirectionnelle:
1) Client --- SYN -> Serveur
2) Le client change d’avis et ne veut plus se connecter
3) Client <-X-ACK-- Le serveur // ACK a été perdu
Le serveur ne voit pas le SYN renvoyé, il pense donc que le client a reçu son ACK et que la connexion est établie. En conséquence, le serveur a une connexion qui ne sera jamais fermée