web-dev-qa-db-fra.com

Est-ce que TCP envoyer un SYN/ACK sur chaque paquet ou seulement sur la première connexion?

J'ai un serveur TCP qui écoute un client entrant, puis lui envoie un paquet de données toutes les secondes. Je me demandais si le paquet SYN/ACK n'était envoyé que lors de la connexion initiale. Il ressemble donc à ceci:

<client connect>
SYN
ACK
DATA
DATA
DATA
<client disconnect>

Ou est-il envoyé avec chaque paquet, comme ceci?

<client connect>
SYN
ACK
DATA

SYN
ACK
DATA

SYN
ACK
DATA
<client disconnect>

De plus, s'il s'agit du premier cas, le protocole UDP présente-t-il des avantages sur TCP si vous maintenez simplement la connexion ouverte sur une longue période?

38
Daniel T.

C'est un peu comme:

+-------------------------------------------------------+
|     client           network            server        |
+-----------------+                +--------------------|
|    (connect)    | ---- SYN ----> |                    |
|                 | <-- SYN,ACK -- |     (accepted)     |
|   (connected)   | ---- ACK ----> |                    |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

when client sends...
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
|                 |                |                    |
|     (send)      | ---- data ---> |                    |
|                 | <---- ACK ---- |  (data received)   |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

when server sends...
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
|                 |                |                    |
|                 | <--- data ---- |       (send)       |
| (data received) | ---- ACK ----> |                    |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

...and so on, til the connection is shut down or reset

SYN démarre une connexion; vous ne le verrez généralement que lorsque la connexion est établie. Mais toutes les données envoyées via TCP nécessitent un ACK. Chaque octet envoyé doit être comptabilisé, sinon il sera retransmis (ou la connexion réinitialisée (fermée), dans les cas graves).

Les connexions réelles ne ressemblent généralement pas exactement au schéma ci-dessus, mais pour deux raisons:

  • Les ACK peuvent s'accumuler et un ACK peut alors accuser réception de tout ce qui a été reçu. Cela signifie que vous pouvez accuser réception de deux envois ou plus avec un ACK.
  • Un ACK est simplement un drapeau et un champ dans un en-tête TCP. L'envoi d'un fichier nécessite au moins un en-tête de bande passante, plus quelle que soit la couche sur laquelle collent les couches inférieures. Mais les segments de données incluent déjà tout cela ... donc si vous envoyez des données, vous pouvez envoyer un ACK en même temps gratuitement.

La plupart des piles TCP/IP tentent de réduire le nombre d'accus ACK nus sans risquer indûment la retransmission ou la réinitialisation de la connexion. Une conversation comme celle-ci est donc tout à fait possible:

\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
|                 |                |                    |
|                 | <--- data ---- |       (send)       |
| (data received) |                |                    |
|     (send)      | -- data,ACK -> |                    |
|                 |                |  (data received)   |
|                 | <- data,ACK -- |       (send)       |
| (data received) |                |                    |
|  (wait a bit)   | <--- data ---- |       (send)       |
| (data received) |                |                    |
|     (send)      | -- data,ACK -> |                    |
|                 |                |  (data received)   |
|     (send)      | ---- data ---> |   (wait a bit)     |
|                 |                |  (data received)   |
|                 | <- data,ACK -- |       (send)       |
| (data received) |                |                    |
|  (wait a bit)   |   (dead air)   |                    |
|                 | ---- ACK ----> |                    |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

En ce qui concerne UDP, il n'y a pas de concept intégré de SYN et ACK - UDP est par nature "peu fiable" et non orienté connexion, les concepts ne s'appliquent donc pas autant. Votre accusé de réception ne sera généralement que la réponse du serveur. Toutefois, certains protocoles de couche d’application construits au-dessus d’UDP disposeront d’une manière spécifique à chaque protocole d’accuser réception des données envoyées et reçues.

71
cHao

SYN est seulement au début. 

ACK est sur les segments suivants dans les deux sens. [edit] L'ACK définira également une taille de fenêtre. Si la taille de la fenêtre est par exemple 100, l'expéditeur peut envoyer 100 segments avant de recevoir un accusé de réception. Par exemple, si l'expéditeur envoie 100 segments mais que le numéro de segment 50 est perdu, le destinataire recevra 1-49 et 51 -100. Récepteur acceptera ensuite ACK pour 50 (le prochain segment prévu) et définira la taille de la fenêtre sur 1. L'expéditeur renverra 1 segment avec le numéro de séquence 50. Le récepteur acquittera ensuite 101 et définira la taille de la fenêtre à un numéro supérieur [edit]

Les deux sont en réalité des champs dans l'en-tête TCP et peuvent être envoyés avec des données, bien que le SYN et le premier ACK soient généralement sans données.

Donc, aucun des scénarios que vous décrivez n'est tout à fait correct. Le premier est en réalité plus proche de la réalité, mais tous les paquets de données après le SYN doivent inclure un ACK, ainsi qu'un champ de numéro d'accusé de réception qui identifie le numéro du prochain paquet attendu. 

La fin d'une session implique également des poignées de main avec des paquets marqués par FIN et des ACK les concernant.

Les numéros de séquence échangés sont utilisés pour identifier les paquets perdus et activer un mécanisme de nouvelle tentative, ainsi que pour réassembler l'intégralité du flux de paquets dans le bon ordre.

De plus, s'il s'agit du premier cas, le protocole UDP présente-t-il des avantages sur TCP si vous maintenez simplement la connexion ouverte sur une longue période?

Avec UDP, vous ne pouvez pas simplement garder la connexion ouverte sur une longue période. Il n'y a pas de connexion.

Cette séquence de drapeaux SYN/ACK/FIN est ce qui établit une connexion.

Avec UDP, il n'y a pas de SYN ou ACK, la communication est donc à sens unique, la livraison n'est pas garantie et la commande n'est pas préservée. Mais comme il a moins de frais généraux, il est utile lorsque la vitesse est plus importante que la fiabilité, comme dans le cas de la diffusion multimédia en continu. 

C'est un peu simplifié pour le moment, mais c'est le mieux que je puisse faire pour le moment.

Il y a beaucoup plus à ce sujet dans l'entrée wikipedia sur TCP et bien sûr dans les RFC.

10
Don Roby

Imaginez ceci: Cependant, la norme RFC 793 TCP d'origine autorisait l'envoi de données avec le premier paquet SYN. Cependant, ce n'est pas le cas aujourd'hui. Ce que vous obtenez est un paquet SYN séparé lors du lancement de Three-Way-Handshake à partir du demandeur de la connexion. Supposons que A demande à se connecter avec B, donc A envoie un paquet avec un jeu de bits SYN. B répond avec un ACK pour accuser réception et envoie à A les paquets ACK + SYN. Les données peuvent alors être transmises désormais. 

Dordal a une très bonne explication à ce sujet. Cliquez sur ce lien ici.

0
StacknormalFlow