Application client-serveur sur un socket de flux TCP. Programmation réseau - Prise en charge des opérations de session TCP

Application client-serveur sur un socket de flux TCP

L'exemple suivant utilise TCP pour fournir des flux d'octets bidirectionnels fiables et ordonnés. Construisons une application complète qui inclut un client et un serveur. Tout d'abord, nous montrons comment construire un serveur sur des sockets de flux TCP, puis une application cliente pour tester notre serveur.

Le programme suivant crée un serveur qui reçoit les demandes de connexion des clients. Le serveur est construit de manière synchrone, donc l'exécution du thread est bloquée jusqu'à ce que le serveur accepte de se connecter au client. Cette application illustre un serveur simple qui répond à un client. Le client met fin à la connexion en envoyant un message au serveur .

Serveur TCP

La création de la structure du serveur est illustrée dans le schéma fonctionnel suivant :

Ici code complet Programmes SocketServer.cs :

// SocketServer.cs utilisant System ; en utilisant System.Text ; en utilisant System.Net ; en utilisant System.Net.Sockets ; namespace SocketServer ( class Program ( static void Main(string args) ( // Définir le point de terminaison local pour le socket IPHostEntry ipHost = Dns.GetHostEntry("localhost"); IPAddress ipAddr = ipHost.AddressList; IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000 ); // Créer un socket Tcp/Ip Socket sListener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // Affecter le socket au point de terminaison local et écouter les sockets entrants try ( sListener.Bind(ipEndPoint) ; sListener. Listen(10); // Commencer à écouter les connexions while (true) ( ​​​​Console.WriteLine("En attente d'une connexion sur le port (0)", ipEndPoint); // Le programme s'arrête, attendant un entrant connection Socket handler = sListener.Accept(); string data = null; // Nous avons attendu qu'un client tente de se connecter avec nous byte bytes = new byte; int bytesRec = handler.Receive(bytes); data += Encoding.UTF8. GetString(bytes, 0, bytesRec); // Afficher les données sur la console Console.Write("Received texte : " + données + "\n\n" ); // Envoi d'une réponse au client\ string reply = "Merci pour la requête en " + data.Length.ToString() + " characters" ; octet msg = Encoding.UTF8.GetBytes(reply); gestionnaire.Envoyer(msg); si (data.IndexOf(" ") > -1) ( Console.WriteLine("Le serveur a mis fin à la connexion avec le client."); break; ) handler.Shutdown(SocketShutdown.Both); handler.Close(); ) ) catch (Exception ex) ( Console.WriteLine (ex.ToString()); ) enfin ( Console.ReadLine(); ) ) ) )

Regardons la structure de ce programme.

La première étape consiste à définir le point de terminaison local pour le socket. Avant d'ouvrir un socket pour écouter les connexions, vous devez lui préparer une adresse de point de terminaison local. L'adresse de service TCP/IP unique est déterminée par la combinaison de l'adresse IP de l'hôte avec le numéro de port de service qui crée le point de terminaison de service.

La classe DNS fournit des méthodes qui renvoient des informations sur les adresses réseau prises en charge par le périphérique sur le réseau local. Si un périphérique LAN possède plusieurs adresses réseau, la classe DNS renvoie des informations sur toutes les adresses réseau et l'application doit sélectionner l'adresse appropriée à servir dans le tableau.

Créez un IPEndPoint pour le serveur en combinant la première adresse IP hôte obtenue à partir de la méthode Dns.Resolve() avec le numéro de port :

IPHostEntry ipHost = Dns.GetHostEntry("localhost"); Adresse IP ipAddr = ipHost.AddressList ; IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);

Ici, la classe IPEndPoint représente localhost sur le port 11000. Ensuite, nous créons un socket de flux avec une nouvelle instance de la classe Socket. En configurant un point de terminaison local pour écouter les connexions, vous pouvez créer un socket :

Socket sListener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

Énumération AdresseFamille spécifie les schémas d'adressage qu'une instance de la classe Socket peut utiliser pour résoudre une adresse.

En paramètre SocketType Les sockets TCP et UDP diffèrent. Il peut inclure les valeurs suivantes :

dgramme

Prend en charge les datagrammes. La valeur Dgram nécessite que vous spécifiiez Udp pour le type de protocole et InterNetwork dans le paramètre de famille d'adresses.

Brut

Prend en charge l'accès au protocole de transport sous-jacent.

Flux

Prend en charge les sockets de flux. La valeur Stream nécessite que Tcp soit spécifié pour le type de protocole.

Le troisième et dernier paramètre spécifie le type de protocole requis pour le socket. En paramètre ProtocolType vous pouvez spécifier les valeurs les plus importantes suivantes - Tcp, Udp, Ip, Raw.

La prochaine étape devrait être d'assigner la socket avec la méthode Lier(). Lorsqu'un socket est ouvert par un constructeur, aucun nom ne lui est attribué, seul un handle est réservé. La méthode Bind() est appelée pour attribuer un nom au socket du serveur. Pour que le socket client puisse identifier le flux Prise TCP, le programme serveur doit nommer sa socket :

SListener.Bind(ipEndPoint);

La méthode Bind() lie un socket à un point de terminaison local. Vous devez appeler la méthode Bind() avant toute tentative d'appel des méthodes Listen() et Accept().

Maintenant, après avoir créé une socket et lui avoir associé un nom, vous pouvez écouter les messages entrants en utilisant la méthode Ecoutez(). Dans l'état d'écoute, le socket attendra les tentatives de connexion entrantes :

SLÉcouteur.Écoute(10);

Le paramètre définit arriéré (arriéré) A qui spécifie le nombre maximum de connexions en attente de traitement dans la file d'attente. Dans le code ci-dessus, la valeur du paramètre permet d'accumuler jusqu'à dix connexions dans la file d'attente.

Dans l'état d'écoute, vous devez être prêt à accepter de vous connecter avec le client, pour lequel la méthode est utilisée J'accepte(). Cette méthode obtient une connexion client et termine l'association entre les noms de client et de serveur. La méthode Accept() bloque le thread du programme appelant jusqu'à ce qu'une connexion soit reçue.

La méthode Accept() récupère la première demande de connexion de la file d'attente des demandes en attente et crée un nouveau socket pour la gérer. Pendant la création du nouveau socket, le socket d'origine continue d'écouter et peut être utilisé avec le multithreading pour accepter plusieurs demandes de connexion des clients. Aucune application serveur ne doit fermer le socket d'écoute. Il doit continuer à fonctionner avec les sockets créés par la méthode Accept pour traiter les demandes client entrantes.

While (true) ( ​​​​Console.WriteLine("Attente d'une connexion sur le port (0)", ipEndPoint); // Le programme s'arrête, attendant une connexion entrante Socket handler = sListener.Accept();

Une fois que le client et le serveur ont établi une connexion entre eux, vous pouvez envoyer et recevoir des messages en utilisant les méthodes Envoyer() et recevoir() Classe socket.

La méthode Send() écrit les données sortantes dans le socket auquel est connecté. La méthode Receive() lit les données entrantes sur le socket de flux. Lors de l'utilisation d'un système basé sur TCP, une connexion doit être établie entre les sockets avant l'exécution des méthodes Send() et Receive(). Le protocole exact entre deux entités en interaction doit être déterminé à l'avance afin que les applications client et serveur ne se bloquent pas, ne sachant pas qui doit envoyer ses données en premier.

Lorsque l'échange de données entre le serveur et le client est terminé, vous devez fermer la connexion en utilisant les méthodes fermer() et Proche():

Handler.Shutdown(SocketShutdown.Both); gestionnaire.Close();

SocketShutdown est une énumération contenant trois valeurs pour arrêter : Tous les deux- arrête d'envoyer et de recevoir des données sur la socket, recevoir- cesse de recevoir des données sur le socket et envoyer- empêche le socket d'envoyer des données.

Le socket est fermé lorsque la méthode Close() est appelée, ce qui définit également la propriété Connected du socket sur false.

Client sur TCP

Les fonctions utilisées pour créer une application cliente ressemblent plus ou moins à une application serveur. Comme pour le serveur, les mêmes méthodes sont utilisées pour déterminer le point de terminaison, instancier le socket, envoyer et recevoir des données et fermer le socket.

TCP s'intègre naturellement dans l'environnement client/serveur (voir Figure 10.1). Application serveur Bugs(écouter) les demandes de connexion entrantes. Par exemple, les services WWW, de transfert de fichiers ou d'accès au terminal écoutent les demandes des clients. Les communications en TCP sont initiées par les sous-programmes appropriés qui initient la connexion au serveur (voir le chapitre 21 sur l'API socket).

Riz. 10.1. Le client appelle le serveur.

En réalité, le client peut être un autre serveur. Par exemple, les serveurs de messagerie peuvent se connecter à d'autres serveurs de messagerie envoyer des messages E-mail entre ordinateurs.

10.2 Notions TCP

Sous quelle forme les applications doivent-elles envoyer des données en TCP ? Comment TCP transfère-t-il les données vers IP ? Comment les protocoles TCP de transmission et de réception identifient-ils une connexion d'application à application et les éléments de données nécessaires à sa mise en œuvre ? Toutes ces questions trouvent une réponse dans les sections suivantes, qui décrivent les concepts de base de TCP.

10.2.1 Flux de données d'entrée et de sortie

Conceptuel le modèle de connexion suppose qu'une application envoie un flux de données à une application homologue. En même temps, il est capable de recevoir un flux de données de son partenaire de connexion. TCP fournit Un duplex plein(full duplex) mode de fonctionnement dans lequel les deux deux flux données (voir Figure 10.2).


Riz. 10.2. Les applications échangent des flux de données.

10.2.2 Secteur

TCP peut convertir le flux de données sortant d'une application en une forme adaptée au placement dans des datagrammes. Comment?

L'application envoie des données à TCP, et ce protocole les place dans tampon de sortie(tampon d'envoi). Ensuite, TCP coupe des morceaux de données du tampon et les envoie, en ajoutant un en-tête (dans ce cas, segments segment). Sur la fig. 10.3 montre comment les données de tampon de sortie Les TCP sont mis en paquets en segments. TCP transmet le segment à IP pour livraison sous la forme d'un datagramme unique. Le regroupement des données en blocs de la bonne longueur garantit un transfert efficace, de sorte que TCP attendra que la quantité appropriée de données se trouve dans le tampon de sortie avant de créer un segment.


Riz. 10.3 Création d'un segment TCP

10.2.3 Pousser

Cependant, de grandes quantités de données ne sont souvent pas applicables à applications réelles. Par exemple, lorsqu'un programme client d'utilisateur final initie une session interactive avec un serveur distant, l'utilisateur saisit alors uniquement des commandes (suivi d'appuyer sur la touche revenir).

Le programme client de l'utilisateur a besoin de TCP pour savoir que des données sont envoyées à l'hôte distant et pour effectuer cette opération immédiatement. Dans ce cas, il est utilisé extrusion(pousser).

Si vous regardez les opérations dans une session interactive, vous pouvez trouver de nombreuses partitions avec peu de données, et de plus, le popping peut être trouvé dans presque toutes les partitions de données. Cependant, le popping ne doit pas être utilisé pendant les transferts de fichiers (sauf pour le tout dernier segment), et TCP sera en mesure de regrouper les données en segments plus efficacement.

10.2.4 Données urgentes

Le modèle de transfert de données de l'application suppose un flux ordonné d'octets sur son chemin vers la destination. En se référant à nouveau à l'exemple de session interactive, supposons que l'utilisateur appuie sur une touche attention(attention) ou Pause(couper la parole). Demande à distance devrait pouvoir ignorer les octets interférents et répondre à une pression sur une touche dès que possible.

Mécanisme données urgentes(données urgentes) marque les informations spéciales dans le segment comme urgent. Avec cela, TCP indique à son homologue que le segment contient des données urgentes et peut indiquer où il se trouve. Le partenaire doit transmettre ces informations à l'application de destination dès que possible.

10.2.5 Ports d'application

Le client doit identifier le service auquel il souhaite accéder. Cela se fait par la spécification de l'adresse IP du service hôte et de son numéro de port TCP. Comme avec UDP, les numéros de port TCP vont de 0 à 65535. Les ports de 0 à 1023 sont connus comme des ports bien connus et sont utilisés pour accéder aux services standard.

Quelques exemples de ports bien connus et leurs applications correspondantes sont présentés dans le tableau 10.1. Prestations de service Jeter(port 9) et accusé(port 19) sont des versions TCP des services que nous connaissons déjà d'UDP. Gardez à l'esprit que le trafic sur le port TCP 9 est complètement isolé du trafic sur le port UDP 9.


Tableau 10.1 Ports TCP bien connus et leurs applications correspondantes

Port Application La description
9 Jeter Annuler toutes les données entrantes
19 accusé Générateur de caractères. Échange de flux de caractères
20 Données FTP Port de transfert FTP
21 FTP Boîte de dialogue Port pour FTP
23 TELNET Port pour connexion à distance via Telnet
25 SMTP Port du protocole SMTP
110 POP3 Service d'échantillonnage de courrier électronique personnel
119 NNTP Accéder aux actualités en ligne

Qu'en est-il des ports utilisés par les clients ? Dans de rares cas, le client ne s'exécute pas sur un port bien connu. Mais dans de telles situations, voulant ouvrir une connexion, il demande souvent au système d'exploitation de lui attribuer un port inutilisé et non réservé. A la fin de la connexion, le client doit restituer ce port, après quoi le port peut être réutilisé par un autre client. Étant donné qu'il existe plus de 63 000 ports TCP dans le pool de numéros non réservés, les limites de port client peuvent être ignorées.

10.2.6 adresses de socket

Comme nous le savons déjà, la combinaison de l'adresse IP et du port de communication s'appelle adresse de prise. Une connexion TCP est entièrement identifiée par une adresse de socket à chaque extrémité ce composé. Sur la fig. La figure 10.4 montre une connexion entre un client avec une adresse de socket (128.36.1.24, port = 3358) et un serveur avec une adresse de socket (130.42.88.22, port = 21).

Riz. 10.4. adresses de socket

L'en-tête de chaque datagramme contient les adresses IP source et destination. Dans ce qui suit, vous verrez que les numéros de port source et de destination sont spécifiés dans l'en-tête du segment TCP.

Généralement, un serveur est capable de gérer plusieurs clients en même temps. Les adresses de socket uniques d'un serveur sont attribuées simultanément à tous ses clients (voir Figure 10.5).


Riz. 10.5. Plusieurs clients connectés aux adresses de socket du serveur

Étant donné que le datagramme contient un segment de connexion TCP identifié par des adresses IP et des ports, il est très facile pour un serveur de suivre plusieurs connexions aux clients.

10.3 Mécanisme de fiabilité TCP

Dans cette section, nous examinerons le mécanisme TCP utilisé pour fournir des données de manière fiable tout en préservant l'ordre de transfert et en évitant la perte ou la duplication.

10.3.1 Numérotation et confirmation

TCP utilise la numérotation et l'accusé de réception (ACK) pour assurer un transfert de données fiable. Le schéma de numérotation TCP est quelque peu inhabituel : chaque transmis sur la connexion octuor considéré comme ayant un numéro de série. L'en-tête du segment TCP contient un numéro de séquence le premier octet de données de ce segment.

Le destinataire est tenu d'accuser réception des données. Si aucun ACK n'arrive dans l'intervalle de temporisation, les données sont retransmises. Cette méthode s'appelle acquittement positif avec relais(accusé de réception positif avec retransmission).

Le récepteur des données TCP effectue une vérification stricte des numéros de séquence entrants pour vérifier la séquence dans laquelle les données ont été reçues et qu'il n'y a pas de pièces perdues. Étant donné que l'ACK peut être perdu ou retardé de manière aléatoire, des segments en double peuvent arriver au récepteur. Les numéros de séquence vous permettent de déterminer la duplication des données, qui sont ensuite rejetées.

Sur la fig. La figure 10.6 montre une vue simplifiée du délai d'attente et de la retransmission dans TCP.


Riz. 10.6. Timeout et retransmission en TCP

10.3.2 Champs Port, Sequence et ACK dans l'en-tête TCP

Comme le montre la fig. 10.7, les premiers champs de l'en-tête TCP fournissent de l'espace pour les valeurs de port source et de destination, le numéro de séquence du premier octet des données intégrées et un ACK égal au numéro de séquence Suivant octet attendu à l'autre bout. En d'autres termes, si le TCP reçoit tous les octets jusqu'à 30 de son homologue, ce champ aura la valeur 31, indiquant le segment à transmettre ensuite.


Riz. 10.7. Valeurs initiales dans les champs d'en-tête TCP

Un petit détail est à noter. Supposons que TCP a envoyé les octets 1 à 50 et qu'il n'y a plus de données à envoyer. Si des données sont reçues d'un pair, TCP doit en accuser réception en envoyant un en-tête sans données jointes. Naturellement, la valeur ACK est présente dans cet en-tête. Dans le champ de séquence - la valeur 51, c'est-à-dire numéro d'octet suivant a l'intention envoyer TCP. Lorsque le TCP envoie les données suivantes, le nouvel en-tête TCP aura également la valeur 51 dans le champ de séquence.

10.4 Établissement d'une connexion

Comment les deux applications sont-elles connectées ? Avant la communication, chacun d'eux appelle une routine pour former un bloc de mémoire qui servira à stocker les paramètres TCP et IP de cette connexion, tels que les adresses de socket, le numéro de séquence courant, la valeur de durée de vie initiale, etc.

L'application serveur attend l'apparition d'un client qui, voulant accéder au serveur, émet une requête pour composé(connect) identifiant l'adresse IP et le port du serveur.

Il existe une caractéristique technique. Chaque côté commence à numéroter chaque octet non pas à partir de un, mais à partir de numéro de série aléatoire(Nous verrons pourquoi cela est fait plus tard.) La spécification d'origine conseille de générer le numéro de séquence initial sur la base d'un temporisateur externe 32 bits qui s'incrémente environ toutes les 4 µs.

10.4.1 Scénario de connexion

La procédure de connexion est souvent appelée prise de contact à trois, puisque trois messages sont échangés pour établir une connexion - SYN, SYN et ACK.

Lors de l'établissement d'une connexion, les partenaires échangent trois informations importantes :

1. La quantité d'espace tampon pour la réception des données

2. La quantité maximale de données transportées dans le segment entrant

3. Numéro de séquence initial utilisé pour les données sortantes

Notez que chaque côté utilise les opérations 1 et 2 pour indiquer limites auxquelles l'autre partie agira. Un ordinateur personnel peut avoir un petit tampon de réception, tandis qu'un superordinateur peut avoir un énorme tampon. Structure de la mémoire ordinateur personnel peut limiter les portions de données entrantes à 1 Ko, et le supercalculateur est contrôlé avec de grands segments.

La possibilité de contrôler la manière dont l'autre partie envoie les données est une fonctionnalité importante qui rend TCP/IP évolutif.

Sur la fig. La figure 10.8 montre un exemple de script de connexion. Initiale très simple numéros de séquence pour ne pas surcharger le dessin. Notez que dans cette figure, le client peut recevoir des segments plus volumineux que le serveur.


Riz. 10.8.Établir une connexion

Les opérations suivantes sont effectuées :

1. Le serveur s'initialise et devient prêt à se connecter avec les clients (cet état est appelé ouvert passif - ouvert passif).

2. Le client demande à TCP d'ouvrir une connexion au serveur à l'adresse IP et au port spécifiés (cet état est appelé actif ouvert).

3. Le client TCP reçoit le numéro de séquence initial (en cet exemple- 1000) et envoie segment de synchronisation(segment de synchronisation - SYN). Dans ce segment, le numéro de séquence, la taille de la fenêtre de réception (4K) et la taille du plus grand segment que le client peut recevoir (1460 octets) sont envoyés.

4. Lorsqu'un SYN arrive, le serveur TCP reçoit mien numéro de séquence de départ (3000). Il envoie un segment SYN contenant le numéro de séquence initial (3000), ACK 1001 (ce qui signifie numéroter le premier octet envoyé par le client comme 1001), la taille de la fenêtre de réception (4K) et la taille du plus grand segment que le serveur peut recevoir (1024 octets).

5. Le client TCP, ayant reçu un message SYN/ACK du serveur, renvoie ACK 3001 (le premier octet des données envoyées par le serveur doit être numéroté 3001).

6. Le client TCP demande à son application d'ouvrir une connexion.

7. Le serveur TCP, ayant reçu un message ACK du client TCP, informe son application que la connexion a été ouverte.

Le client et le serveur annoncent leurs règles pour les données reçues, synchronisent leurs numéros de séquence et se préparent à échanger des données. La spécification TCP permet également un autre scénario (pas très bon) où les applications homologues s'ouvrent activement en même temps.

10.4.2 Réglage des valeurs des paramètres IP

La demande d'une application pour établir une connexion peut également spécifier des paramètres pour les datagrammes IP qui transporteront les données de la connexion. Si aucune valeur de paramètre spécifique n'est spécifiée, la valeur par défaut est utilisée.

Par exemple, une application peut choisir la valeur souhaitée pour la priorité IP ou le type de service. Étant donné que chacune des parties connectées définit indépendamment sa propre priorité et son propre type de service, ces valeurs peuvent théoriquement différer pour différentes directions de flux de données. En règle générale, dans la pratique, les mêmes valeurs sont appliquées pour chaque sens d'échange.

Lorsqu'une application utilise des options de sécurité gouvernementales ou militaires, chaque point de terminaison de connexion doit utiliser les mêmes niveaux de sécurité, sinon la connexion échouera.

10.5 Transfert de données

Le transfert de données commence après l'achèvement de la confirmation de création de connexion en trois étapes (voir Figure 10.9). La norme TCP permet d'inclure des données normales dans les segments d'accusé de réception, mais elles ne seront pas livrées à l'application tant que la connexion n'est pas terminée. Pour simplifier la numérotation, des messages de 1000 octets sont utilisés. Chaque segment d'en-tête TCP a un champ ACK identifiant le numéro de séquence d'octets qui devrait être reçu du partenaire de connexion..


Riz. 10.9. Flux de données simple et ACK

Le premier segment envoyé par le client contient des octets de 1001 à 2000. Son champ ACK doit contenir la valeur 3001, qui indique le numéro de séquence d'octets qui devrait être reçu du serveur.

Le serveur répond au client avec un segment contenant 1000 octets de données (commençant par le numéro 3001). Son champ ACK dans l'en-tête TCP indiquera que les octets 1001 à 2000 ont déjà été reçus avec succès, donc le prochain numéro de séquence de segment attendu du client devrait être 2001.

Le client envoie ensuite les segments commençant par les octets 2001, 3001 et 4001 dans cet ordre. Notez que le client n'attend pas de ACK après chaque segment envoyé. Les données sont envoyées au pair jusqu'à ce que son espace tampon soit plein (nous verrons plus loin que le récepteur peut spécifier très précisément la quantité de données à lui envoyer).

Le serveur enregistre débit connexion, en utilisant un seul ACK pour indiquer que tous les segments ont été transférés avec succès.

Sur la fig. La figure 10.10 montre le transfert de données lorsque le premier segment est perdu. Lorsque le délai expire, le segment est retransmis. Notez que lors de la réception d'un segment perdu, le récepteur envoie un ACK accusant réception de la transmission des deux segments.


Riz. 10.10. Perte de données et retransmission

10.6 Fermeture d'une connexion

L'arrêt normal d'une connexion est effectué en utilisant la même procédure de triple poignée de main que lors de l'ouverture d'une connexion. Chaque partie peut commencer à fermer la connexion dans le scénario suivant :

UN:

B :"Bien".

À:"J'ai aussi terminé le travail."

UN:"Bien".

Le scénario suivant est également acceptable (bien qu'il soit utilisé extrêmement rarement) :

UN:"J'ai terminé le travail. Il n'y a plus de données à envoyer."

À:"Bien. Cependant, il y a des données..."

À:"J'ai aussi terminé le travail."

UN:"Bien".

Dans l'exemple ci-dessous, la connexion ferme le serveur, comme c'est souvent le cas pour les communications client/serveur. Dans ce cas, une fois que l'utilisateur est entré dans la session telnet commande de déconnexion (déconnexion du système) le serveur initie une requête pour fermer la connexion. Dans la situation représentée sur la Fig. 10.11, les actions suivantes sont effectuées :

1. L'application sur le serveur demande à TCP de fermer la connexion.

2. Le serveur TCP envoie un segment final (FIN), informant son pair qu'il n'y a plus de données à envoyer.

3. Le client TCP envoie un ACK sur le segment FIN.

4. Le TCP du client indique à son application que le serveur souhaite fermer la connexion.

5. L'application client informe son TCP que la connexion est fermée.

6. Le client TCP envoie un message FIN.

7. Le serveur TCP reçoit le FIN du client et répond par un message ACK.

8. Le TCP du serveur demande à son application de fermer la connexion.


Riz. 10.11. Fermeture d'une connexion

Les deux parties peuvent commencer à fermer en même temps. Dans ce cas, la fermeture normale de la connexion est terminée après que chacun des pairs envoie un message ACK.

10.6.1 Résiliation brutale

L'une ou l'autre des parties peut demander une interruption brutale de la connexion. Ceci est acceptable lorsqu'une application souhaite mettre fin à une connexion, ou lorsque TCP détecte un problème de communication sérieux qu'elle ne peut pas résoudre par elle-même. Une fin brutale est demandée en envoyant un ou plusieurs messages de réinitialisation au pair, comme indiqué par un indicateur spécifique dans l'en-tête TCP.

10.7 Contrôle de flux

Le récepteur TCP est chargé avec le flux de données entrant et détermine la quantité d'informations qu'il peut accepter. Cette restriction affecte l'expéditeur TCP. L'explication suivante de ce mécanisme est conceptuelle et les développeurs peuvent l'implémenter différemment dans leurs produits.

Lors de l'établissement de la connexion, chaque pair alloue de l'espace pour le tampon d'entrée de la connexion et en informe l'autre partie. En règle générale, la taille de la mémoire tampon est exprimée sous la forme d'un nombre entier de tailles de segment maximales.

Le flux de données entre dans le tampon d'entrée et y est stocké jusqu'à ce qu'il soit transmis à l'application (déterminé par le port TCP). Sur la fig. La figure 10-12 montre un tampon d'entrée qui peut prendre 4 Ko.


Riz. 10.12. Fenêtre de réception du tampon d'entrée

L'espace tampon se remplit au fur et à mesure que les données arrivent. Lorsque l'application réceptrice extrait les données de la mémoire tampon, l'espace libéré devient disponible pour les nouvelles données entrantes.

10.7.1 Fenêtre de réception

fenêtre de réception(fenêtre de réception) - tout espace dans le tampon d'entrée qui n'est pas déjà occupé par des données. Les données restent dans le tampon d'entrée jusqu'à ce qu'elles soient utilisées par l'application cible. Pourquoi l'application ne collecte-t-elle pas les données immédiatement ?

Un scénario simple aidera à répondre à cette question. Supposons que le client ait envoyé un fichier à Serveur ftp s'exécutant sur un ordinateur multi-utilisateur très occupé. Le programme FTP doit alors lire les données du tampon et les écrire sur le disque. Lorsque le serveur effectue des opérations d'E/S de disque, le programme attend que ces opérations se terminent. À ce moment, un autre programme peut démarrer (par exemple, selon un horaire) et au moment où le programme FTP redémarre, les données suivantes seront déjà dans la mémoire tampon.

La fenêtre de réception est étendue du dernier octet acquitté jusqu'à la fin du tampon. Sur la fig. 10.12, le tampon entier est d'abord disponible, et donc une fenêtre de réception 4K est disponible. A l'arrivée du premier Ko, la fenêtre de réception sera réduite à 3 Ko (pour simplifier, nous supposerons que chaque segment a une taille de 1 Ko, bien qu'en pratique cette valeur varie en fonction des besoins de l'application). L'arrivée des deux prochains segments de 1K réduira la fenêtre de réception à 1K.

Chaque ACK envoyé par le récepteur contient des informations sur l'état actuel de la fenêtre de réception, en fonction de laquelle le flux de données provenant de la source est régulé.

Pour l'essentiel, la taille du tampon d'entrée est définie au démarrage de la connexion, bien que la norme TCP ne précise pas comment gérer ce tampon. Le tampon d'entrée peut augmenter ou diminuer pour fournir un retour à l'expéditeur.

Que se passe-t-il si un segment entrant peut être placé dans la fenêtre de réception, mais qu'il arrive dans le désordre ? Il est généralement considéré que toutes les implémentations stockent les données entrantes dans la fenêtre de réception et n'envoient un accusé de réception (ACK) que pour un bloc contigu entier de plusieurs segments. ce Le droit chemin, car sinon, la suppression des données dans le désordre dégradera considérablement les performances.

10.7.2 Fenêtre d'envoi

Un système transmettant des données doit suivre deux caractéristiques : la quantité de données déjà envoyées et acquittées, et la taille actuelle de la fenêtre de réception du récepteur. Actif espace d'envoi(espace d'envoi) S'étend du premier octet non acquitté à la gauche de la fenêtre de réception actuelle. Partie la fenêtre utilisé envoyer, indique la quantité de données supplémentaires pouvant être envoyées au partenaire.

Le numéro de séquence initial et la taille de la fenêtre de réception initiale sont définis lors de la configuration de la connexion. Riz. 10.13 illustre certaines des caractéristiques du mécanisme de transfert de données.

1. L'expéditeur démarre avec une fenêtre d'envoi de 4 Ko.

2. L'expéditeur envoie 1 Ko. Une copie de ces données est conservée jusqu'à ce qu'un accusé de réception (ACK) soit reçu car il peut être nécessaire de la retransmettre.

3. Un ACK pour le premier Ko arrive et les 2 Ko de données suivants sont envoyés. Le résultat est montré dans la troisième partie à partir du haut de la Fig. 10.13. Le stockage de 2 Ko continue.

4. Enfin, un ACK arrive pour toutes les données transmises (c'est-à-dire toutes reçues par le récepteur). ACK restaure la taille de la fenêtre d'envoi à 4 Ko.

Riz. 10.13. Fenêtre d'envoi

Plusieurs caractéristiques intéressantes sont à souligner :

■ L'expéditeur n'attend pas d'accusé de réception pour chacun des segments de données qu'il envoie. La seule limite au transfert est la taille de la fenêtre de réception (par exemple, l'expéditeur ne doit transférer que des segments de 4 Ko d'un octet).

■ Supposons que l'expéditeur envoie des données en plusieurs segments très courts (par exemple, 80 octets). Dans ce cas, les données peuvent être reformatées pour une transmission plus efficace (par exemple, en un seul segment).

10.8 En-tête TCP

Sur la fig. La Figure 10.14 montre le format du segment (en-tête TCP et données). L'en-tête commence par les ID de port source et de destination. Champ suivant numéro de série(numéro de séquence) indique la position dans le flux de données sortant que ce segment occupe. Champ ACK(confirmation) contient des informations sur le prochain segment attendu qui doit apparaître dans le flux de données d'entrée.


Riz. 10.14. Segment TCP

Il y a six drapeaux :

Champ décalages de données(Data Offset) contient la taille de l'en-tête TCP en mots de 32 bits. L'en-tête TCP doit se terminer sur une limite de 32 bits.

10.8.1 Option de taille de segment maximale

Paramètre "taille maximale des segments"(taille maximale de segment - MSS) permet de déclarer la plus grande donnée pouvant être reçue et traitée par le système. Cependant, le titre est quelque peu inexact. Généralement en TCP segment traité comme un en-tête plus des données. Cependant taille maximale des segments défini comme:

La taille du plus grand datagramme pouvant être reçu est de 40

En d'autres termes, le MSS reflète le plus grand charge utile au récepteur lorsque les en-têtes TCP et IP ont une longueur de 20 octets. S'il existe des paramètres supplémentaires, leur longueur doit être soustraite de la taille totale. Par conséquent, la quantité de données pouvant être envoyées dans un segment est définie comme :

Valeur MSS déclarée + 40 - (somme des longueurs d'en-tête TCP et IP)

En règle générale, les pairs échangent des valeurs MSS dans les messages SYN initiaux lorsqu'une connexion est ouverte. Si le système n'annonce pas la taille de segment maximale, la valeur par défaut de 536 octets est utilisée.

La taille de segment maximale est codée avec un préambule de 2 octets suivi d'une valeur de 2 octets, c'est-à-dire la plus grande valeur serait 2 16 -1 (65 535 octets).

MSS impose une limite stricte aux données envoyées à TCP : le récepteur ne pourra pas traiter de grandes valeurs. Cependant, l'expéditeur utilise des segments taille plus petite puisque la taille MTU le long de la route est également déterminée pour la connexion.

10.8.2 Utilisation des champs d'en-tête dans une demande de connexion

Le premier segment envoyé pour ouvrir une connexion a un drapeau SYN de 1 et un drapeau ACK de 0. Le SYN initial est le seul un segment qui a un champ ACK de 0. Notez que la sécurité utilise cette fonctionnalité pour détecter les demandes entrantes pour une session TCP.

Champ numéro de série contient numéro de séquence de départ(numéro de séquence initial), champ la fenêtre - dimension initiale fenêtre de réception. Le seul paramètre TCP actuellement défini est la taille de segment maximale (lorsqu'elle n'est pas spécifiée, la valeur par défaut de 536 octets est utilisée) que TCP est censé recevoir. Cette valeur est longue de 32 bits et est généralement présente dans la demande de connexion dans le champ options(Option). La longueur de l'en-tête TCP contenant la valeur MSS est de 24 octets.

10.8.3 Utilisation des champs d'en-tête dans une réponse de connexion

Dans une réponse d'autorisation à une demande de connexion, les deux indicateurs (SYN et ACK) sont définis sur 1. Le système qui répond indique le numéro de séquence de départ dans le champ correspondant et la taille de la fenêtre de réception dans le champ Fenêtre. La taille de segment maximale que le destinataire souhaite utiliser se trouve généralement dans la réponse de connexion (dans le options). Cette valeur peut différer de la valeur de la partie demandant la connexion, c'est-à-dire deux valeurs différentes peuvent être utilisées.

Une demande de connexion peut être rejetée en spécifiant un indicateur de réinitialisation (RST) avec une valeur de 1 dans la réponse.

10.8.4 Sélection d'un numéro de séquence de départ

La spécification TCP suppose que lors de l'établissement d'une connexion, chaque partie choisit numéro de séquence de départ(basé sur la valeur actuelle du temporisateur interne 32 bits). Comment est-il fait?

Imaginez ce qui se passe lorsque le système tombe en panne. Supposons que l'utilisateur ait ouvert une connexion juste avant le plantage et envoyé une petite quantité de données. Après la récupération, le système ne se souvient plus de tout ce qui a été fait avant le crash, y compris les connexions déjà en cours et les numéros de port attribués. L'utilisateur rétablit la connexion. Les numéros de port ne correspondent pas aux affectations d'origine, et certains d'entre eux peuvent déjà être utilisés par d'autres connexions établies quelques secondes avant le crash.

Par conséquent, l'autre côté à la toute fin de la connexion peut ne pas savoir que son partenaire a subi un crash et a ensuite été restauré. Tout cela entraînera de graves dysfonctionnements, notamment lors de son passage pendant longtemps jusqu'à ce que les anciennes données traversent le réseau et se mélangent aux données de la connexion nouvellement créée. La sélection d'une minuterie de démarrage avec une mise à jour (nouveau départ) élimine ces problèmes. Les anciennes données auront une numérotation différente de la plage de numéros de séquence de la nouvelle connexion. Les pirates, lorsqu'ils usurpent une adresse IP source pour un hôte de confiance, tentent d'accéder aux ordinateurs en spécifiant un numéro de séquence de départ prévisible dans le message. Une fonction de hachage cryptographique basée sur des clés internes sert le meilleur moyen pour sélectionner des numéros de départ protégés.

10.8.5 Utilisation courante des champs

Lors de la préparation de l'en-tête TCP pour la transmission, le numéro de séquence du premier octet des données transmises est indiqué dans le champ numéro de série(Numéro de séquence).

Le numéro du prochain octet attendu du partenaire de connexion est saisi dans le champ confirmation(Numéro d'accusé de réception) lorsque le bit ACK est défini sur 1. Champ la fenêtre(Fenêtre) correspond à la taille de la fenêtre de réception actuelle. Ce champ contient le nombre d'octets du numéro d'accusé de réception pouvant être acceptés. Notez que cette valeur permet un contrôle précis du flux de données. Avec cette valeur, le pair indique l'état réel de la fenêtre de réception lors de la session d'échange.

Si une application indique une opération push TCP, alors le fanion PUSH est mis à 1. Le TCP récepteur DOIT répondre à ce fanion en délivrant rapidement des données à l'application dès que l'expéditeur souhaite les transmettre.

Le fanion URGENT, s'il est mis à 1, implique un transfert de données urgent, et le pointeur correspondant doit pointer sur le dernier octet des données urgentes. Une utilisation typique des données urgentes consiste à envoyer des signaux depuis le terminal pour annuler ou abandonner.

Les données urgentes sont souvent appelées informations hors bande(hors bande). Cependant, ce terme est inexact. Les données urgentes sont envoyées sur un flux TCP normal, bien que des implémentations individuelles puissent avoir des mécanismes spéciaux pour indiquer à une application que des données urgentes sont arrivées, et l'application doit examiner le contenu des données urgentes avant que tous les octets du message n'arrivent.

L'indicateur RESET est mis à 1 lorsqu'une connexion doit être interrompue. Le même indicateur est défini dans la réponse lorsqu'un segment est reçu qui n'est associé à aucune des connexions TCP actuelles.

L'indicateur FIN est défini sur 1 pour les messages de fermeture de connexion.


10.8.6 Somme de contrôle

La somme de contrôle IP concerne uniquement l'en-tête IP, tandis que la somme de contrôle TCP est calculée pour l'ensemble du segment ainsi que le pseudo-en-tête généré à partir de l'en-tête IP. Lors du calcul de la somme de contrôle TCP, le champ correspondant est mis à 0. Dans la fig. La figure 10-15 montre un pseudo-en-tête très similaire à celui utilisé dans la somme de contrôle UDP.


Riz. 10.15. Champ de pseudo-en-tête inclus dans la somme de contrôle TCP

La longueur TCP est calculée en ajoutant la longueur de l'en-tête TCP à la longueur des données. La somme de contrôle TCP est obligatoire, pas comme dans UDP. La somme de contrôle du segment entrant est d'abord calculée par le récepteur, puis comparée au contenu du champ de somme de contrôle de l'en-tête TCP. Si les valeurs ne correspondent pas, le segment est ignoré.

10.9 Exemple de segment TCP

Riz. 10.16, protocole analyseur Renifleur par Network General, est une séquence de segments TCP. Les trois premiers segments établissent la connexion entre le client et le serveur telnet. Le dernier segment transporte 12 octets de données.


Riz. 10.16. Affichage de l'en-tête TCP par l'analyseur Sniffer

Analyseur Renifleur traduit la plupart des valeurs en décimal. Cependant, les valeurs des indicateurs sont sorties au format hexadécimal. Le drapeau avec la valeur 12 est 010010. La somme de contrôle est également sortie en hexadécimal.

10.10 Prise en charge du fonctionnement de la session

10.10.1 Sondage de fenêtre

Un expéditeur rapide et un récepteur lent peuvent former une fenêtre de réception de 0 octet. Ce résultat est appelé fermeture de fenêtre(Fermer la fenêtre). Lorsqu'il y a de l'espace libre pour mettre à jour la taille de la fenêtre de réception, ACK est utilisé. Cependant, si un tel message est perdu, les deux parties devront attendre indéfiniment.

Pour éviter cette situation, l'expéditeur définit enregistrer la minuterie(minuterie persistante) lors de la fermeture d'une fenêtre premium. La valeur du temporisateur est le délai de retransmission. A la fin du timer, un segment est envoyé au partenaire fenêtre de détection(sonde de fenêtre ; certaines implémentations incluent des données). La sonde amène l'homologue à renvoyer un ACK qui signale l'état actuel de la fenêtre.

Si la fenêtre est toujours de taille zéro, la valeur du temporisateur persistant est doublée. Ce processus est répété jusqu'à ce que la valeur de la minuterie atteigne un maximum de 60 s. TCP continuera d'envoyer des messages de sonde toutes les 60 secondes, jusqu'à ce qu'une fenêtre s'ouvre, jusqu'à ce que l'utilisateur termine le processus ou jusqu'à ce que l'application expire.

10.11 Terminer une session

10.11.1 Temporisation

Le partenaire de connexion peut tomber en panne ou être complètement interrompu en raison d'une défaillance de passerelle ou de liaison. Pour empêcher la retransmission des données dans TCP, il existe plusieurs mécanismes.

Lorsqu'il atteint le premier seuil de retransmission (relais), TCP demande à IP de rechercher le routeur défaillant et informe en même temps l'application du problème. TCP continue d'envoyer des données jusqu'à ce que la deuxième valeur limite soit atteinte et ne ferme alors la connexion.

Bien sûr, avant que cela ne se produise, il peut y avoir un message ICMP indiquant que la destination est inaccessible pour une raison quelconque. Dans certaines implémentations, même après cela, TCP continuera d'essayer d'accéder à la destination jusqu'à l'expiration du délai d'expiration (le problème peut alors être résolu). Ensuite, l'application est informée que la destination est inaccessible.

Une application peut définir son propre délai de livraison des données et effectuer ses propres opérations lorsque cet intervalle expire. Généralement, la connexion est interrompue.

10.11.2 Maintenir une connexion

Lorsqu'une connexion inachevée a des données à envoyer pendant une longue période, elle obtient le statut d'inactivité. Pendant une période d'inactivité, un plantage du réseau ou une défaillance de la liaison physique peut se produire. Dès que le réseau redeviendra opérationnel, les partenaires continueront à échanger des données sans interrompre la session de communication. Cette stratégie répondait aux exigences du ministère de la Défense.

Cependant, toute connexion - active ou inactive - consomme beaucoup de mémoire de l'ordinateur. Certains administrateurs doivent restituer les ressources inutilisées aux systèmes. Par conséquent, de nombreuses implémentations TCP sont capables d'envoyer un message sur maintenir une connexion(keep-alive) qui teste les connexions inactives. De tels messages sont envoyés périodiquement au partenaire pour vérifier son existence dans le réseau. La réponse doit être des messages ACK. L'utilisation de messages persistants est facultative. Si le système a cette capacité, l'application peut la remplacer par ses propres moyens. Période estimée défaut car le délai de maintenance de la connexion est de deux heures complètes !

Rappelons que l'application peut régler sa propre minuterie, selon laquelle, à son niveau, elle décidera de la fin de la connexion.

10.12 Performance

Quelle est l'efficacité de TCP ? Les performances des ressources sont affectées par de nombreux facteurs, les principaux étant la mémoire et la bande passante (voir Figure 10.17).


Riz. 10.17. Facteurs de performances TCP

La bande passante et les retards dans le réseau physique utilisé limitent considérablement le débit. Une mauvaise qualité de transfert de données entraîne un grand volume de datagrammes rejetés, ce qui provoque des retransmissions et réduit par conséquent l'efficacité de la bande passante.

Le côté réception doit fournir suffisamment d'espace tampon pour permettre à l'expéditeur de transférer des données sans interruption de fonctionnement. Ceci est particulièrement important pour les réseaux à forte latence, où il y a beaucoup de temps entre l'envoi des données et la réception des ACK (et aussi lors de la négociation de la taille de la fenêtre). Pour maintenir un flux constant de données depuis la source, le côté réception doit disposer d'une fenêtre non inférieure au produit de la bande passante et du délai.

Par exemple, si la source peut envoyer des données à un débit de 10 000 octets/s et qu'il faut 2 secondes pour renvoyer un ACK, la fenêtre de réception de l'autre côté doit avoir une taille d'au moins 20 000 octets, sinon le flux de données sera ne pas être continu. Un tampon de réception de 10 000 octets réduira le débit de moitié.

Un autre facteur important pour la performance est la capacité de l'hôte à répondre aux événements hautement prioritaires et à exécuter rapidement changement de contexte, c'est à dire. effectuer une opération et passer à une autre. L'hôte peut prendre en charge de manière interactive plusieurs utilisateurs locaux, des processus d'arrière-plan par lots et des dizaines de connexions de communication simultanées. La commutation de contexte vous permet de servir toutes ces opérations, masquant la charge sur le système. Les implémentations qui intègrent TCP/IP au noyau du système d'exploitation peuvent réduire considérablement la charge liée à l'utilisation de la commutation de contexte.

Ressources CPU des ordinateurs sont requis pour les opérations de traitement d'en-tête TCP. Si le processeur ne peut pas calculer rapidement les sommes de contrôle, cela entraîne une diminution de la vitesse de transfert des données sur le réseau.

En outre, les développeurs doivent chercher à simplifier la configuration des paramètres TCP afin qu'un administrateur réseau puisse les personnaliser en fonction de leurs besoins locaux. Par exemple, la possibilité d'ajuster la taille de la mémoire tampon pour la bande passante et la latence du réseau améliorera considérablement les performances. Malheureusement, de nombreuses implémentations ne prêtent pas suffisamment attention à ce problème et codent en dur les paramètres de communication.

Supposons que l'environnement réseau soit parfait : il y a suffisamment de ressources et le changement de contexte est plus rapide que les cow-boys ne tirent leurs armes. Est-ce que d'excellentes performances seront obtenues ?

Pas toujours. La qualité du développement du logiciel TCP est également importante. Au fil des ans, de nombreux problèmes de performances ont été diagnostiqués et résolus dans diverses implémentations TCP. On peut considérer que le meilleur logiciel sera celui qui respecte la RFC 1122 qui définit les exigences pour la couche communication des hébergeurs Internet.

Une exception tout aussi importante et l'application des algorithmes de Jacobson, Kern et Partridge (ces algorithmes intéressants seront discutés ci-dessous).

Les développeurs de logiciels peuvent obtenir des avantages significatifs en créant des programmes qui éliminent les petits transferts de données inutiles et ont des minuteries intégrées pour libérer les ressources réseau qui ne sont pas actuellement utilisées.

10.13 Algorithmes d'amélioration des performances

Passant à une introduction à la partie plutôt complexe de TCP, nous examinerons les mécanismes d'amélioration des performances et de gestion des dégradations de débit. Cette section aborde les problèmes suivants :

démarrage lent(démarrage lent) empêche l'utilisation d'une part importante trafic réseau pour une nouvelle session, ce qui peut entraîner des frais généraux.

■ Guérir de Syndrome de la fenêtre désemparée(Silly Window Syndrome) empêche les applications mal conçues d'inonder le réseau de messages.

ACK retardé(ACK retardé) réduit la congestion en réduisant le nombre de messages d'accusé de réception de transfert de données indépendants.

Délai de retransmission calculé(calcul du délai de retransmission) repose sur la négociation de session en temps réel, réduisant les retransmissions inutiles tout en ne causant pas de retards importants pour les échanges de données réellement nécessaires.

■ Blocage du transfert TCP lorsque surcharges sur le réseau permet aux routeurs de revenir à leur mode d'origine et de partager les ressources réseau pour toutes les sessions.

■ Expédition ACK en double(accusé de réception en double) à la réception d'un segment hors séquence, permet aux pairs de retransmettre avant qu'un délai d'attente ne se produise.

10.13.1 Démarrage lent

Si tous les appareils électroménagers sont allumés en même temps chez vous, le réseau électrique sera surchargé. À réseaux informatiquesdémarrage lent empêche les fusibles du secteur de griller.

Une nouvelle connexion qui commence instantanément à envoyer une grande quantité de données sur un réseau déjà occupé peut entraîner des problèmes. L'idée d'un démarrage lent est de s'assurer que la nouvelle connexion démarre avec succès avec une augmentation lente du taux de transfert de données en fonction de la charge réelle sur le réseau. L'expéditeur est limité par la taille de la fenêtre de chargement, et non par la plus grande fenêtre de réception.

fenêtre de chargement(fenêtre de congestion) commence par une taille de 1 segment. Pour chaque segment avec un ACK reçu avec succès, la taille de la fenêtre de chargement est augmentée de 1 segment, tant qu'elle reste plus petite que la fenêtre de réception. Si le réseau n'est pas congestionné, la fenêtre de chargement atteindra progressivement la taille de la fenêtre de réception. Dans un état de transfert normal, ces fenêtres auront la même taille.

Notez qu'un démarrage lent n'est pas si lent. Après le premier ACK, la taille de la fenêtre de chargement est de 2 segments, et après un ACK réussi pour deux segments, la taille peut augmenter jusqu'à 8 segments. En d'autres termes, la taille de la fenêtre augmente de façon exponentielle.

Supposons qu'au lieu de recevoir un ACK, une situation de dépassement de délai s'est produite. Le comportement de la fenêtre de chargement dans ce cas est décrit ci-dessous.

10.13.2 Syndrome de fenêtre désemparée

Dans les premières implémentations de TCP/IP, les développeurs ont rencontré le phénomène Syndrome de la fenêtre désemparée(Silly Window Syndrome - SWS), qui s'est manifesté assez souvent. Pour comprendre ce qui se passe, considérez le scénario suivant, qui entraîne des conséquences indésirables, mais c'est tout à fait possible :

1. L'application d'envoi envoie les données rapidement.

2. L'application réceptrice lit 1 octet de données à partir du tampon d'entrée (c'est-à-dire lentement).

3. Le tampon d'entrée se remplit rapidement après la lecture.

4. L'application réceptrice lit 1 octet et le TCP envoie un ACK signifiant "J'ai de l'espace libre pour 1 octet de données".

5. L'application émettrice envoie un paquet TCP de 1 octet sur le réseau.

6. Le TCP récepteur envoie un ACK signifiant "Merci. J'ai reçu le paquet et je n'ai plus espace libre".

7. L'application réceptrice lit à nouveau 1 octet et envoie un ACK, et l'ensemble du processus est répété.

Une application de réception lente attend longtemps l'arrivée des données et pousse constamment les informations reçues vers le bord gauche de la fenêtre, effectuant une opération totalement inutile qui génère du trafic supplémentaire sur le réseau.

Les situations réelles, bien sûr, ne sont pas si extrêmes. Un expéditeur rapide et un récepteur lent échangeront de petits blocs de données (par rapport à la taille de segment maximale) et basculeront sur une fenêtre de réception presque pleine. Sur la fig. 10.18 montre les conditions d'apparition du syndrome de la "fenêtre stupide".


Riz. 10.18. Recevoir un tampon de fenêtre avec un très petit espace libre

Résoudre ce problème est facile. Dès que la fenêtre de réception est réduite d'une longueur inférieure à la taille cible donnée, TCP commence à tromper l'expéditeur. Dans cette situation, TCP ne doit pas pointer l'expéditeur vers Additionnel espace dans la fenêtre lorsque l'application réceptrice lit les données du tampon par petits morceaux. Au lieu de cela, les ressources libérées doivent être gardées secrètes de l'expéditeur jusqu'à ce qu'il y en ait suffisamment. Une seule taille de segment est recommandée, sauf si le tampon d'entrée entier stocke un seul segment (dans ce dernier cas, une taille égale à la moitié du tampon est utilisée). La taille cible que TCP doit signaler peut être exprimée comme suit :

minimum (1/2 tampon d'entrée, taille de segment maximale)

TCP commence à tricher lorsque la taille de la fenêtre est inférieure à cette taille et dira la vérité lorsque la taille de la fenêtre n'est pas inférieure à la valeur donnée par la formule. Notez qu'il n'y a aucun mal à l'expéditeur, car l'application réceptrice ne serait toujours pas en mesure de traiter une grande partie des données qu'elle attend.

La solution proposée est facile à vérifier dans le cas évoqué ci-dessus avec la sortie de ACK pour chacun des octets reçus. La même méthode convient également au cas où le tampon d'entrée peut stocker plusieurs segments (comme cela se produit souvent dans la pratique). L'expéditeur rapide remplira le tampon d'entrée, mais le destinataire indiquera qu'il n'a pas d'espace libre pour stocker des informations et n'ouvrira pas cette ressource tant que sa taille n'aura pas atteint le segment entier.

10.13.3 Algorithme de Nagle

L'expéditeur doit, quel que soit le destinataire, éviter d'envoyer des segments très courts en accumulant des données avant l'envoi. L'algorithme de Nagle implémente une idée très simple pour réduire le nombre de datagrammes courts envoyés sur le réseau.

L'algorithme recommande de retarder le transfert de données (et le popping) en attendant un ACK à partir de données précédemment transmises. Les données accumulées sont envoyées après réception d'un ACK à un élément d'information précédemment envoyé, ou après réception pour envoyer des données de la taille d'un segment complet, ou à la fin d'un délai d'attente. Cet algorithme ne doit pas être utilisé pour les applications en temps réel qui doivent envoyer des données aussi rapidement que possible.

10.13.4 ACK retardé

Un autre mécanisme d'amélioration des performances est la façon dont ACK est retardé. La réduction du nombre d'ACK réduit la quantité de bande passante qui peut être utilisée pour envoyer d'autres trafics. Si le partenaire TCP retarde légèrement l'envoi de l'ACK, alors :

■ Plusieurs segments peuvent être acquittés avec un seul ACK.

■ L'application réceptrice peut recevoir une certaine quantité de données dans l'intervalle de temporisation, c'est-à-dire. l'en-tête de sortie peut être inclus dans l'ACK et aucun message séparé n'a besoin d'être généré.

Afin d'éviter les retards lors de la transmission d'un flux de segments complets (par exemple, lors de l'échange de fichiers), un ACK doit être envoyé pour au moins un segment complet sur deux.

De nombreuses implémentations utilisent un délai d'attente de 200 ms. Mais un ACK retardé ne réduit pas le taux de change. Lorsqu'un court segment arrive, il y a encore suffisamment d'espace libre dans le tampon d'entrée pour recevoir de nouvelles données, et l'expéditeur peut continuer le transfert (de plus, la retransmission est généralement beaucoup plus lente). Si un segment entier arrive, vous devez y répondre avec un message ACK à la même seconde.

10.13.5 Délai de retransmission

Après avoir envoyé le segment, TCP définit une minuterie et surveille l'arrivée d'un ACK. Si un ACK n'est pas reçu dans le délai imparti, TCP retransmet le segment (relais). Cependant, quelle devrait être la période de temporisation ?

S'il est trop court, l'expéditeur inondera le réseau de segments inutiles qui dupliquent les informations déjà envoyées. Un timeout trop long empêchera les segments réellement corrompus lors du transfert d'être rapidement réparés, ce qui réduira le débit.

Comment choisir le bon intervalle pour le timeout ? Une valeur adaptée à un LAN haut débit ne conviendra pas à une connexion à distance avec de nombreux hits. Par conséquent, le principe "une valeur pour toutes les conditions" est clairement inadapté. De plus, même pour une connexion spécifique existante, les conditions du réseau peuvent changer et les retards peuvent augmenter ou diminuer.

Algorithmes de Jacobson, Kern et Partridge (décrits dans les articles , Van Jacobson et Amélioration des estimations de temps aller-retour dans des protocoles de transport fiables, Karn et Partridge) permettent à TCP de s'adapter aux conditions changeantes du réseau. Ces algorithmes sont recommandés pour une utilisation dans de nouvelles implémentations. Nous les passerons brièvement en revue ci-dessous.

Le bon sens dicte que la meilleure base pour estimer le délai d'expiration correct pour une connexion particulière pourrait être de suivre temps d'un cycle(temps aller-retour) comme l'intervalle entre l'envoi des données et la réception de la confirmation de leur réception.

bonnes décisions pour les valeurs suivantes peuvent être obtenues sur la base de statistiques élémentaires (voir Figure 10.19), ce qui aidera à calculer le délai d'attente. Cependant, ne vous fiez pas aux moyennes, car plus de la moitié des scores seront supérieurs à la moyenne statistique. En considérant une paire de variances, de meilleures estimations peuvent être obtenues qui tiennent compte de la distribution normale et réduisent une latence de retransmission trop longue.


Riz. 10.19. Répartition des temps de cycle

Il n'est pas nécessaire d'effectuer une grande quantité de calculs pour obtenir des estimations mathématiques formelles des écarts. Vous pouvez utiliser des estimations assez approximatives basées sur la valeur absolue de la différence entre la dernière valeur et l'estimation moyenne :

Dernier écart = | Dernier cycle - Moyenne |

Pour calculer la valeur de temporisation correcte, un autre facteur à prendre en compte est la modification du temps de cycle due aux conditions actuelles du réseau. Ce qui s'est passé en ligne à la dernière minute est plus important que ce qui s'est passé il y a une heure.

Supposons que vous calculiez la moyenne du cycle pour une très longue session. Supposons qu'au début, le réseau était peu chargé et que nous ayons déterminé 1 000 petites valeurs, mais qu'il y ait ensuite eu une augmentation du trafic avec une augmentation significative du temps de retard.

Par exemple, si 1000 valeurs donnaient une valeur moyenne de 170 unités, mais que 50 valeurs étaient mesurées avec une moyenne de 282, alors la moyenne actuelle serait :

170x1000/1050 + 282x50/1050 = 175

Plus raisonnable serait temps de cycle lissé(Smoothed Round-Trip Time - SRTT), qui tient compte de la priorité des valeurs ultérieures :

Nouveau SRTT = (1 – α)×(ancien SRTT) + α×Valeur du dernier cycle

La valeur de α est comprise entre 0 et 1. Augmenter un entraîne une plus grande influence du temps de cycle courant sur la moyenne lissée. Parce que les ordinateurs peuvent rapidement diviser par des puissances de 2 en déplaçant nombres binairesà droite, α vaut toujours (1/2) n (habituellement 1/8), donc :

Nouveau SRTT = 7/8×ancien SRTT + 1/8×Dernier temps de cycle

Le tableau 10.2 montre comment la formule pour SRTT s'ajuste à la valeur SRTT actuelle de 230 unités lorsqu'un changement dans les conditions du réseau entraîne une augmentation séquentielle du temps de cycle (en supposant qu'aucune temporisation ne se produise). Les valeurs de la colonne 3 sont utilisées comme valeurs de la colonne 1 pour la ligne suivante du tableau (c'est-à-dire l'ancien SRTT).


Tableau 10.2 Calcul du temps de cycle lissé

Ancien SRTT Dernier RTT (7/8)×(ancien SRTT) + (1/8)×(RTT)
230.00 294 238.00
238.00 264 241.25
241.25 340 253.59
253.59 246 252.64
252.64 201 246.19
246.19 340 257.92
257.92 272 259.68
259.68 311 266.10
266.10 282 268.09
268.09 246 265.33
265.33 304 270.16
270.16 308 274.89
274.89 230 269.28
269.28 328 276.62
276.62 266 275.29
275.29 257 273.00
273.00 305 277.00

Maintenant se pose la question du choix d'une valeur pour le timeout de retransmission. Une analyse des temps de cycle montre un écart important de ces valeurs par rapport à la moyenne actuelle. Il est logique de fixer une limite à l'ampleur des écarts (écarts). Les bonnes valeurs pour le délai de retransmission (appelé Retransmission TimeOut - RTO dans les normes RFC) sont données par la formule suivante avec une variance lissée contrainte (SDEV) :

T = Délai de retransmission = SRTT + 2×SDEV

T = SRTT + 4×SDEV

Pour calculer SDEV, déterminez d'abord la valeur absolue de l'écart actuel :

DEV = | Durée du dernier cycle - Ancien SRTT |

Ensuite, une formule de lissage est utilisée pour tenir compte de la dernière valeur :

Nouveau SDEV = 3/4×ancien SDEV + 1/4×DEV

Une question demeure - lequel prendre Valeurs initiales? Recommandé:

Temporisation initiale = 3 s

SRTT initial = 0

SDEV initiale = 1,5 s

Van Jacobson a défini un algorithme rapide qui calcule très efficacement le délai de retransmission.

10.13.6 Exemple de statistiques

Dans quelle mesure le délai d'attente calculé ci-dessus fonctionnera-t-il ? Lors de la mise en œuvre de la valeur obtenue, des améliorations significatives des performances ont été observées. Un exemple serait les statistiques de commande netstat reçu sur le système tigre- un serveur Internet accessible par de nombreux hôtes du monde entier.


1510769 paquets (314955304 octets) reçus en séquence

système tigre moins de 2,5 % des segments de données TCP ont été retransmis. Pour un million et demi de segments de données entrants (le reste étant de purs ACK), seuls 0,6 % étaient dupliqués. Dans ce cas, il convient de tenir compte du fait que le niveau de pertes dans les données d'entrée correspond approximativement au niveau des segments de sortie. Ainsi, le trafic de retransmission inutile représente environ 0,6 % du trafic total.

10.13.7 Calculs après nouvelle soumission

Les formules ci-dessus utilisent la valeur du temps de cycle comme intervalle entre l'envoi d'un segment et la réception d'un accusé de réception. Cependant, supposons qu'aucun accusé de réception n'est reçu pendant la période de temporisation et que les données doivent être renvoyées.

L'algorithme de Kern suppose que dans ce cas, le temps de cycle ne doit pas être modifié. La valeur actuelle lissée du temps de cycle et écart lissé conservent leurs valeurs jusqu'à ce qu'un accusé de réception soit reçu pour envoyer un segment sans le renvoyer. À partir de ce moment, les calculs reprennent sur la base des valeurs stockées et des nouvelles mesures.

10.13.8 Actions après retransmission

Mais que se passe-t-il avant la réception de la confirmation ? Après une retransmission, le comportement de TCP change radicalement, principalement en raison de la perte de données due à la congestion du réseau. Par conséquent, la réponse au renvoi des données sera :

■ Taux de retransmission réduit

■ Luttez contre la congestion du réseau en réduisant le trafic global

10.13.9 Freinage exponentiel

Après une retransmission, l'intervalle de temporisation est doublé. Cependant, que se passe-t-il lorsque la minuterie déborde à nouveau ? Les données seront à nouveau envoyées et la période de retransmission doublera à nouveau. Ce processus est appelé freinage exponentiel(recul exponentiel).

Si le défaut réseau persiste, la période de temporisation doublera jusqu'à ce que la temporisation prédéfinie soit atteinte. valeur maximum(habituellement - 1 minute). Après le délai d'attente, un seul segment peut être envoyé. Le timeout se produit également si le temps d'avance est dépassé. valeur de consigne pour le nombre de transferts de données sans réception d'un ACK.

10.13.10 Réduire la congestion en réduisant les données envoyées sur le réseau

Réduire la quantité de données envoyées est un peu plus compliqué que les mécanismes évoqués ci-dessus. Il commence à fonctionner, comme le démarrage lent déjà mentionné. Mais, comme une limite est fixée au niveau de trafic, ce qui peut initialement poser des problèmes, le taux de change va en fait ralentir en raison de l'augmentation de la taille de la fenêtre de chargement pour un segment. Vous devez définir les valeurs de bordure pour une réelle réduction de la vitesse d'envoi. Tout d'abord, le seuil de danger est calculé :

Limite - 1/2 minimum (fenêtre de chargement actuelle, fenêtre de réception du partenaire)

Si la valeur résultante est supérieure à deux segments, elle est utilisée comme limite. Sinon, la taille de la bordure est définie sur deux segments. L'algorithme de récupération complet nécessite :

■ Définissez la taille de la fenêtre de chargement sur un segment.

■ Pour chaque ACK reçu, augmentez la taille de la fenêtre de chargement d'un segment jusqu'à ce que la limite soit atteinte (un peu comme le mécanisme de démarrage lent).

■ Ensuite, avec chaque ACK reçu, ajoutez une valeur plus petite à la fenêtre de chargement, qui est choisie en fonction du taux d'augmentation dans un segment pour le temps de cycle (l'augmentation est calculée comme MSS/N, où N est la taille de la fenêtre de chargement en segments).

Le scénario du cas idéal peut être une représentation simpliste du fonctionnement du mécanisme de récupération. Supposons que la fenêtre de réception de l'homologue (et la fenêtre de chargement actuelle) était de 8 segments avant la détection du délai d'attente, et que la limite est définie sur 4 segments. Si l'application réceptrice lit instantanément les données du tampon, la taille de la fenêtre de réception restera à 8 segments.

■ 1 segment est envoyé (fenêtre de chargement = 1 segment).

■ ACK reçu - 2 segments sont envoyés.

■ ACK reçu pour 2 segments - 4 segments sont envoyés (limite atteinte).

■ Reçu ACK pour 4 segments. 5 segments sont envoyés.

■ Reçu ACK pour 5 segments. 6 segments sont envoyés.

■ ACK reçu pour 6 segments. 7 segments sont envoyés.

■ ACK reçu pour 7 segments. 8 segments sont envoyés (la fenêtre de chargement est à nouveau de taille égale à la fenêtre de réception).

Étant donné que toutes les données envoyées doivent faire l'objet d'un accusé de réception pendant le délai de retransmission, le processus se poursuit jusqu'à ce que la fenêtre de chargement atteigne la taille de la fenêtre de réception. Les événements qui se produisent sont illustrés à la fig. 10h20. La taille de la fenêtre augmente de manière exponentielle, doublant pendant la période de démarrage lent, et une fois la limite atteinte, l'augmentation est linéaire.


Riz. 10h20. Limite de débit à terme pendant la congestion

10.13.11 ACK dupliqués

Dans certaines implémentations, une fonctionnalité facultative est utilisée - la soi-disant réexpédition rapide(retransmission rapide) - afin d'accélérer la retransmission des données sous certaines conditions. Son idée principale est liée au fait que le destinataire envoie des ACK supplémentaires indiquant une lacune dans les données reçues.

A la réception d'un segment dans le désordre, le récepteur renvoie un ACK pointant sur le premier octet. perdu données (voir Figure 10.21).


Riz. 10.21. ACK en double

L'expéditeur n'effectue pas de retransmission instantanée des données car IP peut normalement fournir des données au destinataire sans séquence d'envoi. Mais lorsque plusieurs ACK supplémentaires sont reçus pour la duplication de données (par exemple, trois), le segment manquant sera envoyé sans attendre la fin du délai d'attente.

Notez que chaque ACK en double indique la réception d'un segment de données. Plusieurs ACK en double indiquent clairement que le réseau est capable de fournir suffisamment de données, et donc pas trop chargé. Dans le cadre de l'algorithme global, une petite réduction de la taille de la fenêtre de chargement est effectuée avec une augmentation réelle du trafic réseau. Dans ce cas, le processus de redimensionnement drastique lors de la restauration de l'œuvre ne s'applique pas.

Selon la norme Exigences de l'hôte(exigences de l'hôte) TCP doit effectuer le même démarrage lent que celui décrit ci-dessus lors de l'extinction de la source. Cependant, le signalement n'est ni ciblé ni efficace, car la connexion qui a reçu le message peut ne pas générer trop de trafic. Spécification actuelle Exigences du routeur(exigences du routeur) spécifie que les routeurs ne devrait pas envoyer des messages de suppression de source.

10.13.13 Statistiques TCP

Enfin, regardons les messages statistiques de la commande netstat, pour voir de nombreux mécanismes décrits ci-dessus en action.

Les segments sont appelés paquets.
879137 paquets de données (226966295 octets)
21815 paquets de données (8100927 octets) retransmis
Réexpédition.
132957 paquets ack-only (104216 retardés)
Notez le grand nombre

ACK retardés.

Son d'ouverture de fenêtre

taille zéro.

Ce sont les messages SYN et FIN.
762469 accusés de réception (pour 226904227 octets)
Alerte d'arrivée de paquet

Hors de la séquence.

1510769 paquets (314955304 octets)
9006 paquets complètement dupliqués (867042 octets)
Le résultat d'un timeout avec un réel

livraison de données.

74 paquets avec du dup. données (12193 octets dupés)
Pour être plus efficace

certaines données ont été reconditionnées pour inclure des octets supplémentaires lorsqu'elles sont renvoyées.

13452 paquets en panne (2515087 octets)
530 paquets (8551 octets) de données après fenêtre
Peut-être que ces données étaient

inclus dans les messages sonores.

402 paquets reçus après fermeture
Ce sont des répétitions ultérieures

Envoi en cours.

108 rejetés pour les mauvaises sommes de contrôle
Somme de contrôle TCP non valide.
0 rejeté pour les champs de décalage d'en-tête incorrects
7 rejeté car paquet trop court
14677 connexions établies (y compris les acceptations)
18929 connexions fermées (dont 643 chutes)
4100 connexions embryonnaires abandonnées
572187 segments mis à jour rtt (sur 587397 tentatives)
Tentatives de modification infructueuses

temps de cycle, car l'ACK n'est pas arrivé avant l'expiration du délai,

26 connexions abandonnées par rexmit timeout
Tentatives ultérieures infructueuses

renvoyer, indiquant une connexion perdue.

Délais de détection

fenêtre zéro.

Vérifier les délais d'attente

connexion inactive.

472 connexions abandonnées par keepalive

10.14 Conformité aux exigences du développeur

La norme TCP actuelle exige que les implémentations respectent strictement la procédure de démarrage lent lors de l'initialisation d'une connexion et utilisent les algorithmes de Kern et Jacobson pour estimer le délai de renvoi et contrôler la charge. Des tests ont montré que ces mécanismes conduisent à des améliorations significatives des performances.

Que se passe-t-il lorsque vous installez un système qui ne respecte pas strictement ces normes ? Il ne fournira pas de performances adéquates pour ses propres utilisateurs et sera un mauvais voisin pour les autres systèmes du réseau, empêchant le fonctionnement normal d'être restauré après une surcharge temporaire et générant un trafic excessif entraînant la perte de datagrammes.

10.15 Obstacles à la performance

TCP a prouvé sa flexibilité en fonctionnant sur des réseaux avec des débits en bauds de centaines ou de millions de bits par seconde. Ce protocole a permis de bons résultats dans le moderne réseaux locaux avec les topologies Ethernet, Token-Ring et Fiber Distributed Data Interface (FDDI), ainsi que pour les liaisons à faible vitesse ou les connexions longue distance (comme les liaisons par satellite).

TCP est conçu pour répondre à des conditions extrêmes, telles que la congestion du réseau. Cependant, dans version actuelle Le protocole a des fonctionnalités qui limitent les performances des technologies émergentes qui offrent une bande passante dans les centaines et les milliers de mégaoctets. Pour comprendre les problèmes qui se posent, considérons un exemple simple (quoique irréaliste).

Supposons que lorsque vous déplacez un fichier entre deux systèmes, vous souhaitiez échanger un flux continu aussi efficacement que possible. Supposons que :

■ La taille maximale du segment de destination est de 1 Ko.

■ Fenêtre de réception - 4 Ko.

La bande passante vous permet d'envoyer deux segments par 1 s.

■ L'application réceptrice consomme les données à mesure qu'elles arrivent.

■ Les messages ACK arrivent après 2 secondes.

L'expéditeur est capable d'envoyer des données en continu. Après tout, lorsque le volume alloué à la fenêtre est plein, un ACK arrive, permettant d'envoyer un autre segment :

Après 2 s :

RECEVOIR ACK DU SEGMENT 1, PEUT ENVOYER LE SEGMENT 5.
RECEVOIR ACK DU SEGMENT 2, PEUT ENVOYER LE SEGMENT 6.
RECEVOIR ACK DU SEGMENT 3, PEUT ENVOYER LE SEGMENT 7.
RECEVOIR ACK DU SEGMENT 4, PEUT ENVOYER LE SEGMENT 8.

Après 2 s de plus :

RECEVOIR ACK DU SEGMENT 5, PEUT ENVOYER LE SEGMENT 9.

Si la fenêtre de réception n'était que de 2K, l'expéditeur devrait attendre une seconde sur deux avant d'envoyer les données suivantes. En effet, pour conserver un flux continu de données, la fenêtre de réception doit être au minimum :

Fenêtre = bande passante × temps de cycle

Bien que l'exemple soit quelque peu exagéré (pour fournir des chiffres plus simples), une petite fenêtre peut entraîner des problèmes avec les connexions satellite à latence élevée.

Voyons maintenant ce qui se passe avec les connexions à haut débit. Par exemple, si la bande passante et le taux de transfert sont mesurés à 10 Mbps, mais que le temps de cycle est de 100 ms (1/10 de seconde), alors pour un flux continu, la fenêtre de réception doit stocker au moins 1 000 000 bits, soit . 125 000 octets. Mais le plus grand nombre, qui peut être écrit dans le champ d'en-tête de la fenêtre de réception TCP, est 65536.

Un autre problème se pose lorsque vitesses élevéeséchange, car les numéros de série s'épuiseront très rapidement. Si la connexion peut envoyer des données à un débit de 4 Go / s, les numéros de séquence doivent être mis à jour toutes les secondes. Il n'y aura aucun moyen de faire la distinction entre les anciens datagrammes en double qui ont été retardés de plus d'une seconde lorsqu'ils ont voyagé sur Internet, et les nouvelles données fraîches.

De nouvelles recherches sont activement menées pour améliorer TCP/IP et supprimer les obstacles mentionnés ci-dessus.

10.16 Fonctions TCP

Ce chapitre couvre les nombreuses fonctionnalités de TCP. Les principaux sont listés ci-dessous :

■ Associer des ports à des connexions

■ Initialisation des connexions par confirmation en trois étapes

■ Exécution d'un démarrage lent pour éviter la congestion du réseau

■ Segmentation des données en transit

■ Numérotation des données

■ Gestion des segments en double entrants

■ Calcul de la somme de contrôle

■ Régulation du flux de données à travers la fenêtre de réception et la fenêtre d'envoi

■ Mettre fin à une connexion manière établie

■ Mettre fin à la connexion

■ Transfert de données urgentes

■ Confirmation de renvoi positif

■ Calcul du délai de retransmission

■ Réduction du trafic inverse pendant la congestion du réseau

■ Signalisation des segments hors service

■ Sonder la fermeture de la fenêtre de réception

10.17 États TCP

Une connexion TCP passe par plusieurs étapes : une connexion est établie par un échange de messages, puis des données sont envoyées, puis la connexion est fermée par un échange de messages spéciaux. Chaque étape du fonctionnement de la connexion correspond à un certain condition cette connexion. Le logiciel TCP à chaque extrémité de la connexion surveille en permanence l'état actuel de l'autre côté de la connexion.

Ci-dessous, nous examinerons brièvement un changement typique de l'état d'un serveur et d'un client situés à différentes extrémités de la connexion. Notre objectif n'est pas de donner une description exhaustive de tous les états possibles lors du transfert de données. Il est donné dans la RFC 793 et ​​le document Exigences de l'hôte.

Lors de l'établissement des connexions, le serveur et le client passent par des séquences d'états similaires. Les états du serveur sont présentés dans le Tableau 10.3 et les états du client sont présentés dans le Tableau 10.4.


Tableau 10.3 Séquence d'état du serveur

État du serveur Événement La description
FERMÉ L'état factice avant de commencer la configuration de la connexion.
Ouverture passive par application serveur.
ÉCOUTEZ (suivi) Le serveur attend une connexion du client.
Serveur TCP reçoit SYN et envoie SYN/ACK. Le serveur a reçu un SYN et a envoyé un SYN/ACK. Va attendre ACK.
SYN REÇU Le serveur TCP reçoit un ACK.
ÉTABLI (installé) ACK reçu, connexion ouverte.

Tableau 10.4 Séquence d'état du client

Si les pairs essayaient d'établir une connexion les uns avec les autres en même temps (ce qui est extrêmement rare), chacun passerait par les états CLOSED, SYN-SENT, SYN-RECEIVED et ESTABLISHED.

Les parties finales de la connexion restent dans l'état ESTABLISHED jusqu'à ce que l'une des parties procède à fermeture connexion en envoyant un segment FIN. Lors d'une clôture normale, la partie qui initie cette clôture passe par les états indiqués dans le tableau 10.5. Son partenaire passe par les états présentés dans le tableau 10.6.


Tableau 10.5 La séquence d'état du côté qui ferme la connexion

États secondaires de fermeture Événement La description
ÉTABLI L'application locale demande la fermeture de la connexion.
TCP envoie FIN/ACK.
FIN-ATTENDRE-1 La soirée de clôture attend la réponse du partenaire. Rappelez-vous que de nouvelles données peuvent encore arriver du partenaire.
TCP reçoit un ACK.
FIN-ATTENDRE-2 La partie fermante a reçu un ACK du pair, mais n'a pas encore reçu de FIN. Le côté fermant attend FIN tout en acceptant les données entrantes.
TCP reçoit FIN/ACK.
Envoie un ACK.
TEMPS D'ATTENTE La connexion est maintenue dans un état indéterminé pour permettre l'arrivée ou le rejet des données dupliquées ou du FIN dupliqué encore existant dans le réseau. La période d'attente correspond au double de l'estimation de la durée de vie maximale du segment.
FERMÉ

Tableau 10.6 Séquence d'état du partenaire de fermeture de la connexion

Statut de partenaire Événement La description
ÉTABLI TCP reçoit FIN/ACK.
ATTENTE PROCHE FIN est arrivé.
TCP envoie ACK.
TCP attend que son application ferme la connexion. À ce stade, l'application peut envoyer une quantité assez importante de données.
L'application locale initie la fermeture de la connexion.
TCP envoie FIN/ACK.
LAST-ACK TCP attend un ACK final.
TCP reçoit un ACK.
FERMÉ Suppression de toutes les informations de connexion.

10.17.1 Analyse des états de connexion TCP

Équipe netstat -an permet de vérifier l'état actuel de la connexion. Ce qui suit montre les connexions dans les états écouter, démarrage, établi, fermeture et temps d'attente.

Notez que le numéro de port de connexion est répertorié à la fin de chaque adresse externe. Vous pouvez voir qu'il existe un trafic TCP pour les files d'attente d'entrée et de sortie.

Pro Recv-Q Send-Q Adresse locale Adresse étrangère (état)
TCP 0 0 128.121.50.145.25 128.252.223.5.1526 SYN_RCVD
Tcp 0 0 128.121.50.145.25 148.79.160.65.3368 ÉTABLI
Tcp 0 0 127.0.0.1.1339 127.0.0.1.111 TIME_WAIT
Tcp 0 438 128.121.50.145.23 130.132.57.246.2219 ÉTABLI
Tcp 0 0 128.121.50.145.25 192.5.5.1.4022 TIME_WAIT
Tcp 0 0 128.121.50.145.25 141.218.1.100.3968 TIME_WAIT
Tcp 0 848 128.121.50.145.23 192.67.236.10.1050 ÉTABLI
Tcp 0 0 128.121.50.145.1082 128.121.50.141.6000 ÉTABLI
TCP 0 0 128.121.50.145.1022 128.121.50.141.1017 ÉTABLI
Tcp 0 0 128.121.50.145.514 128.121.50.141.1020 CLOSE_WAIT
Tcp 0 1152 128.121.50.145.119 192.67.239.23.3572 ÉTABLI
Tcp 0 0 128.121.50.145.1070 192.41.171.5.119 TIME_WAIT
TCP 579 4096 128.121.50.145.119 204.143.19.30.1884 ÉTABLI
Tcp 0 0 128.121.50.145.119 192.67.243.13.3704 ÉTABLI
Tcp 0 53 128.121.50.145.119 192.67.236.218.2018 FIN_WAIT_1
Tcp 0 0 128.121.50.145.119 192.67.239.14.1545 ÉTABLI

10.18 Remarques sur la mise en œuvre

Dès le début, le protocole TCP a été conçu pour l'interaction des équipements réseau de divers fabricants. La spécification TCP ne spécifie pas exactement comment les structures internes de l'implémentation doivent fonctionner. Ces questions sont laissées aux développeurs, qui sont appelés à trouver les meilleurs mécanismes pour chaque implémentation particulière.

Même RFC 1122 (document Exigences de l'hôte- exigences de l'hôte) laisse beaucoup de place à la variation. Chacune des fonctions implémentées est marquée d'un certain niveau de compatibilité :

■ MAI (Autorisé)

■ NE DOIT PAS

Malheureusement, il existe parfois des produits qui ne mettent pas en œuvre les exigences MUST. En conséquence, les utilisateurs subissent les inconvénients de performances réduites.

Certaines bonnes pratiques de mise en œuvre ne sont pas couvertes par les normes. Par exemple, la sécurité peut être améliorée en limitant l'utilisation de ports bien connus aux processus privilégiés sur le système si le système opérateur cette méthode est prise en charge. Pour améliorer les performances, les implémentations doivent effectuer le moins de copies et de déplacements possible des données envoyées ou récupérées.

Interface de programmation d'applications standard non déterminé(ainsi que la politique de sécurité), afin qu'il y ait un champ d'activité libre pour expérimenter différents ensembles d'outils logiciels. Cependant, cela peut entraîner des interfaces de programmation différentes sur chaque plate-forme et empêcher le déplacement des logiciels d'application entre les plates-formes.

En fait, les développeurs basent leurs boîtes à outils sur l'API Socket, empruntée à Berkeley. L'importance de l'interface de programmation a augmenté avec l'avènement de WINSock (Windows Socket), entraînant une prolifération de nouvelles applications de bureau pouvant s'exécuter sur n'importe quelle interface WINSock compatible avec la pile TCP / IP.

10.19 Lectures complémentaires

La norme TCP d'origine est définie dans la RFC 793. Les mises à niveau, les correctifs et les exigences de compatibilité sont couverts dans la RFC 1122. Kern (Kash) et Partridge (Partridge) ont publié un article Améliorer les estimations aller-retour dans des protocoles de transport fiables Dans la revue Actes de l'ACM SIGCOMM 1987. L'article de Jacobson Évitement et contrôle de la congestion apparaît dans Actes de l'atelier ACM SIGCOMM 1988. Jacobson a également publié plusieurs RFC révisant des algorithmes pour améliorer les performances.

Parcourez les protocoles réseau.

TCP et UDP sont tous deux des protocoles de couche transport. UDP est un protocole sans connexion avec livraison de paquets non garantie. TCP (Transmission Control Protocol) est un protocole orienté connexion avec une livraison garantie des paquets. Tout d'abord, une poignée de main se produit (Hello | Hello | Let's chat? | Come on.), Après quoi la connexion est considérée comme établie. De plus, les paquets sont envoyés dans les deux sens sur cette connexion (il y a une conversation), et avec une vérification si le paquet a atteint le destinataire. Si le colis est perdu, ou atteint, mais avec une batte somme de contrôle, puis il est renvoyé ("répéter, n'a pas entendu"). Ainsi, TCP est plus fiable, mais il est plus difficile en termes de mise en œuvre et, par conséquent, nécessite plus de cycles/mémoire, ce qui n'est pas la dernière valeur pour les microcontrôleurs. Des exemples de protocoles d'application qui utilisent TCP incluent FTP, HTTP, SMTP et bien d'autres.

TL;DR

HTTP (Hypertext Transfer Protocol) est un protocole d'application par lequel le serveur envoie des pages à notre navigateur. HTTP est maintenant omniprésent dans Internet pour obtenir des informations sur des sites Web. Sur la photo, la lampe est sur un microcontrôleur avec un système d'exploitation intégré, dans lequel les couleurs sont définies via un navigateur.

Le protocole HTTP est basé sur du texte et assez simple. En fait, voici à quoi ressemble la méthode GET envoyée par l'utilitaire netcat à l'adresse IPv6 locale du serveur avec des lumières :

~$ nc fe80::200:e2ff:fe58:b66b%mazko 80<

La méthode HTTP est généralement un mot anglais court écrit en majuscules, sensible à la casse. Chaque serveur doit prendre en charge au moins les méthodes GET et HEAD. Outre les méthodes GET et HEAD, les méthodes POST, PUT et DELETE sont souvent utilisées. La méthode GET permet de demander le contenu de la ressource spécifiée, dans notre cas ici GET /b HTTP/1.0 où le chemin /b est responsable de la couleur (bleu). Réponse du serveur :

HTTP/1.0 200 OK Serveur : Contiki/2.4 http://www.sics.se/contiki/ Connexion : close Cache-Control : no-cache, no-store, must-revalidate Pragma : no-cache Expire : 0 Content- taper : texte/html Contiki RVB

Le rouge est éteint

Le vert est éteint

Le bleu est allumé

Le code d'état (nous en avons 200) fait partie de la première ligne de la réponse du serveur. C'est un entier à trois chiffres. Le premier chiffre indique la classe d'état. Le code de réponse est généralement suivi d'une phrase explicative séparée par des espaces en anglais, qui explique à la personne la raison d'une telle réponse. Dans notre cas, le serveur a fonctionné sans erreurs, tout était dans un tas (OK).

La requête et la réponse contiennent toutes deux des en-têtes (chaque ligne est un champ d'en-tête séparé, la paire nom-valeur est séparée par deux points). Les en-têtes se terminent par une ligne vide, après quoi les données peuvent suivre.

Mon navigateur refuse d'ouvrir une adresse IPv6 locale, une adresse supplémentaire est donc enregistrée dans le firmware du microcontrôleur et le même préfixe doit également être attribué à l'interface réseau virtuelle du simulateur :

~$ sudo ip addr add abcd::1/64 dev mazko # linux ~$ netsh interface ipv6 set address mazko abcd::1 # windows ~$ curl http://