Contacts

Programmation réseau - TCP. Application client-serveur sur un socket de flux TCP Flux de données d'entrée et de sortie

Les serveurs qui implémentent ces protocoles dans réseau d'entreprise fournir au client une adresse IP, une passerelle, un masque de réseau, des serveurs de noms et même une imprimante. Les utilisateurs n'ont pas besoin de configurer manuellement leurs hôtes pour utiliser le réseau.

Le système d'exploitation QNX Neutrino implémente un autre protocole plug-and-play appelé AutoIP, qui est une ébauche du protocole de l'IETF réglage automatique... Ce protocole est utilisé sur les petits réseaux pour attribuer des adresses IP aux hôtes qui sont en lien local. Le protocole AutoIP détermine indépendamment l'adresse IP locale du canal, en utilisant un schéma de négociation avec d'autres hôtes et sans contacter un serveur central.

Utiliser PPPoE

PPPoE signifie Point-to-Point Protocol over Ethernet. Ce protocole encapsule les données à transmettre sur un réseau Ethernet ponté.

PPPoE est une spécification de connexion utilisateur Réseaux Ethernetà Internet via une connexion haut débit, telle qu'une ligne spécialisée, un périphérique sans fil ou un modem câble. L'utilisation du protocole PPPoE et d'un modem large bande fournit aux utilisateurs des réseau informatique accès individuel authentifié aux réseaux de données à haut débit.

PPPoE combine Ethernet avec PPP pour créer efficacement une connexion distincte à un serveur distant pour chaque utilisateur. Le contrôle d'accès, la comptabilité des connexions et la sélection du fournisseur de services sont spécifiques à l'utilisateur et non à l'hôte. L'avantage de cette approche est que ni la compagnie de téléphone ni le fournisseur de services Internet n'ont à fournir de support spécial pour cela.

Contrairement aux connexions commutées, les connexions DSL et modem câble sont toujours actives. Étant donné que la connexion physique à un fournisseur de services distant est partagée par plusieurs utilisateurs, une méthode de comptabilité est nécessaire pour enregistrer les expéditeurs et les destinations du trafic et facturer les utilisateurs. PPPoE permet à un utilisateur et à un hôte distant qui participent à une communication d'apprendre les adresses réseau de l'autre lors d'un échange initial appelé détection(Découverte). Après une session entre un utilisateur individuel et nœud distant(par exemple, par votre FAI) est défini, cette session peut être surveillée pour le chargement. Dans de nombreux foyers, hôtels et entreprises, l'accès Internet est partagé sur des lignes d'abonnés numériques utilisant Ethernet et PPPoE.

Une connexion PPPoE se compose d'un client et d'un serveur. Le client et le serveur fonctionnent avec n'importe quelle interface proche des spécifications Ethernet. Cette interface est utilisée pour émettre des adresses IP aux clients avec la liaison de ces adresses IP aux utilisateurs et, éventuellement, aux postes de travail, au lieu d'une authentification basée uniquement poste de travail... Le serveur PPPoE crée une connexion point à point pour chaque client.

Établir une session PPPoE

Afin de créer une session PPPoE, vous devez utiliser le servicepppoed... Moduleio-pkt- * nFournit des services de protocole PPPoE. Vous devez d'abord couririo-pkt- *avecpilote approprié... Exemple:

Application client-serveur sur socket de streaming TCP

Dans l'exemple suivant, nous utilisons TCP pour fournir des flux d'octets bidirectionnels ordonnés et fiables. Construisons une application complète qui comprend un client et un serveur. Nous montrons d'abord comment construire un serveur sur des sockets de streaming 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, par conséquent, l'exécution du thread est bloquée jusqu'à ce que le serveur accepte de se connecter au client. Cette application montre 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 :

Voici le code complet du programme 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éfinit le point de terminaison local pour le socket IPHostEntry ipHost = Dns.GetHostEntry ("localhost"); IPAddress ipAddr = ipHost.AddressList; IPEndPoint ipEndPoint = new IPEndPoint (ipAddr, 11 ); // Créer un socket Tcp / Ip sListener = new Socket (ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // Attribuer le socket au point de terminaison local et écouter les sockets entrants essayer (sListener.Bind (ipEndPoint ); sListener. Listen (10); // Commence à écouter les connexions pendant que (true) (Console.WriteLine ("En attente d'une connexion sur le port (0)", ipEndPoint); // Le programme se met en pause, en attente d'une connexion entrante Gestionnaire de socket = sListener.Accept (); string data = null; // Nous avons attendu qu'un client essaie 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 "); // Envoie une réponse au client \ string reply = "Merci pour la demande dans" + data.Length.ToString () + "characters"; octet msg = Encoding.UTF8.GetBytes (réponse); gestionnaire.Envoyer (msg); if (données.IndexOf (" ")> -1) (Console.WriteLine (" Le serveur a terminé la connexion avec le client. "); Break;) handler.Shutdown (SocketShutdown.Both); handler.Close ();)) catch (Exception ex) (Console.WriteLine (ex.ToString ());) enfin (Console.ReadLine ();))))

Jetons un coup d'œil à la structure de ce programme.

La première étape consiste à établir un 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 dans 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 une adresse appropriée dans la baie à servir.

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

IPHostEntry ipHost = Dns.GetHostEntry ("localhost"); IPAddress ipAddr = ipHost.AddressList; IPEndPoint ipEndPoint = nouveau IPEndPoint (ipAddr, 11000);

Ici, la classe IPEndPoint représente localhost sur le port 11000. Ensuite, créez un socket de flux avec une nouvelle instance de la classe Socket. Avec un point de terminaison local configuré pour écouter les connexions, un socket peut être créé :

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.

Dans le paramètre Type de prise il existe des sockets TCP et UDP. Dans celui-ci, vous pouvez définir, entre autres, les valeurs suivantes :

Dgram

Prend en charge les datagrammes. La valeur Dgram vous oblige à spécifier 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 streaming. La valeur Stream nécessite que Tcp soit spécifié pour le type de protocole.

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

L'étape suivante devrait être d'affecter le socket à l'aide de la méthode Lier ()... Lorsqu'une socket est ouverte par le constructeur, aucun nom ne lui est attribué, seul un descripteur est réservé. La méthode Bind() est appelée pour attribuer un nom au socket serveur. Pour que le socket client puisse identifier le socket de streaming TCP, le programme serveur doit nommer son socket :

SListener.Bind (ipEndPoint);

La méthode Bind() lie le socket au 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éé un socket et lui avoir associé un nom, vous pouvez écouter les messages entrants en utilisant la méthode Ecoutez ()... Dans un état d'écoute, le socket attendra les tentatives de connexion entrantes :

SLauditeur.Écoutez (10) ;

Le paramètre définit arriéré indiquant nombre maximal connexions en attente dans la file d'attente. Dans le code donné, la valeur du paramètre permet d'accumuler jusqu'à dix connexions dans la file d'attente.

Dans l'état d'écoute, il faut être prêt à consentir à la connexion avec le client, pour lequel la méthode est utilisée J'accepte ()... Cette méthode permet d'obtenir une connexion client et de finaliser l'association nom client/serveur. La méthode Accept() bloque le thread de l'appelant jusqu'à ce qu'une connexion arrive.

La méthode Accept() récupère la première demande de connexion dans la file d'attente des demandes en attente et crée un nouveau socket pour la gérer. Bien qu'un nouveau socket soit créé, le socket d'origine continue d'écouter et peut être multithread pour recevoir 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 gérer les demandes clientes entrantes.

While (true) (Console.WriteLine ("En attente d'une connexion sur le port (0)", ipEndPoint); // Le programme s'interrompt, 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 de socket.

La méthode Send() écrit les données sortantes sur le socket auquel la connexion est établie. La méthode Receive() lit les données entrantes sur un socket de flux. Lors de l'utilisation d'un système basé sur TCP, une connexion doit être établie entre les sockets avant d'exécuter les méthodes Send() et Receive(). Le protocole exact entre les 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 leurs 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.Fermer ();

SocketShutdown est une énumération contenant trois valeurs à arrêter : Les deux- arrête d'envoyer et de recevoir des données par la socket, Recevoir- arrête de recevoir des données sur la socket, et Envoyer- arrête l'envoi de données par la socket.

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.

Voyager sur des protocoles réseau.

TCP et UDP sont tous deux des protocoles de couche transport. UDP est un protocole sans connexion avec une livraison de paquets non sécurisée. TCP (Transmission Control Protocol) est un protocole orienté connexion avec une livraison de paquets garantie. Il y a d'abord une poignée de main (Bonjour. | Bonjour. | Discutons ? | Allez.), Après quoi la connexion est considérée comme établie. De plus, les paquets sont envoyés dans les deux sens via cette connexion (il y a une conversation) et avec une vérification si le paquet a atteint le destinataire. Si le paquet est perdu, ou arrivé, mais avec une somme de contrôle binaire, alors il est envoyé à nouveau ("répétition, n'a pas entendu"). Ainsi, TCP est plus fiable, mais il est plus complexe du point de vue de la mise en œuvre et, par conséquent, nécessite plus d'horloge/mémoire, ce qui n'est pas le moins important pour les microcontrôleurs. Les exemples de protocoles d'application utilisant 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 désormais omniprésent sur le World Wide Web pour récupérer des informations à partir de sites Web. L'image montre une lumière sur un microcontrôleur avec un système d'exploitation à bord, dans lequel les couleurs sont définies via le navigateur.

Le protocole HTTP est textuel et assez simple. En fait, c'est à quoi ça ressemble GET méthode envoyé par l'utilitaire netcat à l'adresse IPv6 locale du serveur bulbe :

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

La méthode HTTP est généralement un mot anglais court en majuscules, sensible à la casse. Chaque serveur doit prendre en charge au moins les méthodes GET et HEAD. En plus des méthodes GET et HEAD, les méthodes POST, PUT et DELETE sont souvent utilisées. La méthode GET est utilisée pour demander le contenu de la ressource spécifiée, dans notre cas voici 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 : fermer Cache-Control : no-cache, no-store, must-revalidate Pragma : no-cache Expire : 0 Content- tapez : 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 de la condition. Le code de réponse est généralement suivi d'une phrase explicative en anglais, séparée par un espace, qui explique à la personne la raison de cette réponse particulière. Dans notre cas, le serveur a fonctionné sans erreur, tout en grappe (OK).

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

Mon navigateur refuse d'ouvrir l'adresse IPv6 locale, donc une adresse supplémentaire est écrite 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: //



TCP s'intègre naturellement dans l'environnement client/serveur (voir Figure 10.1). Application serveur écoute(écouter) les demandes de connexion entrantes. Par exemple, les services WWW, File Transfer ou Terminal Access écoutent les demandes des clients. La communication en TCP est initiée par les routines appropriées qui initient la connexion au serveur (voir chapitre 21 sur l'interface de programmation 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 pour transférer des messages électroniques entre ordinateurs.

10.2 Concepts TCP

Sous quelle forme les applications doivent-elles envoyer des données via TCP ? Comment TCP transfère-t-il les données vers IP ? Comment les protocoles TCP d'envoi et de réception identifient-ils la connexion entre les applications 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 TCP de base.

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

Conceptuel le modèle de connexion suppose que l'application envoie un flux de données à l'application homologue. Dans le 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 simultanément deux flux données (voir la figure 10.2).


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

10.2.2 Segments

TCP peut transformer le flux de données quittant l'application en une forme adaptée au placement dans des datagrammes. Comment?

L'application transmet les données en TCP, et ce protocole les met en tampon de sortie(envoyer le tampon). Ensuite, TCP coupe des morceaux de données du tampon et les envoie, en ajoutant un en-tête (dans ce cas, segments- segment). En figue. 10.3 montre comment les données de tampon de sortie TCP est conditionné en segments. TCP transmet le segment à IP pour livraison sous forme de datagramme séparé. Le regroupement des données en morceaux de longueur correcte garantit que les données sont envoyées efficacement. TCP attendra donc que la quantité de données correspondante apparaisse dans le tampon de sortie avant de créer un segment.


Riz. 10.3 Création d'un segment TCP

10.2.3 Éjection

Cependant, de grandes quantités de données sont souvent impossibles à appliquer aux applications du monde réel. Par exemple, lorsqu'un programme client d'utilisateur final lance une session interactive avec serveur distant, alors l'utilisateur ne saisit que des commandes (suivi de l'appui sur la touche Revenir).

Le programme client de l'utilisateur a besoin que TCP soit informé de l'envoi de données à l'hôte distant et qu'il le fasse immédiatement. Dans ce cas, utilisez éjection(pousser).

Si vous regardez les opérations dans une session interactive, vous pouvez trouver de nombreux segments avec peu de données, et de plus, des bosses peuvent être trouvées dans presque tous les segments de données. Cependant, le push ne doit pas être appliqué pendant les transferts de fichiers (sauf pour le tout dernier segment), et TCP sera en mesure de compresser les données le plus efficacement possible en segments.

10.2.4 Données urgentes

Le modèle de transfert d'application suppose l'application d'un flux ordonné d'octets qui se rend à la destination. En se référant à nouveau à l'exemple de session interactive, supposons que l'utilisateur ait appuyé sur la touche attention(attention) ou Pause(interrompre). L'application distante doit être capable de sauter les octets perturbateurs et de répondre à la frappe dès que possible.

Mécanisme données urgentes(données urgentes) marque les informations spéciales dans le segment comme urgent. Par cela, TCP informe 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 applicatifs

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

Plusieurs 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 chargé(port 19) sont les versions TCP des services que nous connaissons déjà d'UDP. N'oubliez pas que le trafic du port TCP 9 est complètement isolé du trafic du port UDP 9.


Tableau 10.1 Ports TCP couramment connus et leurs applications correspondantes

Port Application La description
9 Jeter Annulation de toutes les données entrantes
19 chargé Générateur de symboles. Échange de flux de personnages
20 FTP-Données Port de transfert de données FTP
21 FTP Port pour la conversation FTP
23 TELNET Port pour l'enregistrement Telnet à distance
25 SMTP port SMTP
110 POP3 Récupération du service de messagerie pour les ordinateurs personnels
119 NNTP Accès aux actualités en ligne

Qu'en est-il des ports utilisés par les clients ? Dans de rares cas, le client ne fonctionne pas via 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 est obligé de restituer ce port, après quoi le port peut être réutilisé par un autre client. Comme il y a plus de 63 000 ports TCP dans le pool de numéros non réservés, les restrictions 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 prise. Une connexion TCP est entièrement identifiée par l'adresse de socket à chaque extrémité de cette connexion. En figue. 10.4 montre la connexion entre un client au socket (128.36.1.24, port = 3358) et un serveur au socket (130.42.88.22, port = 21).

Riz. 10.4. Adresses de socket

Chaque en-tête de datagramme contient les adresses IP source et de destination. On verra plus loin que les numéros de port source et destination sont indiqués dans l'en-tête du segment TCP.

En règle générale, 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 client.

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 maintenant 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 connexion transférée octuor est considéré comme ayant un numéro séquentiel. L'en-tête du segment TCP contient le 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 contrôle strictement les numéros de séquence entrants pour s'assurer que les données sont reçues de manière cohérente et qu'il n'y a pas de pièces manquantes. Étant donné que les ACK peuvent être perdus ou retardés de manière aléatoire, des segments en double peuvent arriver au destinataire. Les numéros de séquence vous permettent d'identifier les données en double qui sont ensuite supprimées.

En figue. 10.6 montre un aperçu simplifié du délai d'attente TCP et de la retransmission.


Riz. 10.6. Timeout et retransmission dans TCP

10.3.2 Champs de port, de séquence et d'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 la place pour les ports source et destination, le numéro de séquence du premier octet de données intégrées et un ACK égal au numéro de séquence Suivant octet attendu à l'autre extrémité. En d'autres termes, si TCP reçoit tous les octets jusqu'au 30 de son homologue, ce champ aura une valeur de 31, indiquant le segment à transmettre.


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

Un petit détail est à noter. Supposons que TCP ait envoyé des octets de 1 à 50 ou plus, il n'y a aucune donnée à envoyer. Si des données sont reçues d'un partenaire, TCP est obligé d'en accuser réception, pour lequel il enverra un en-tête sans aucune donnée qui lui est connectée. Naturellement, cet en-tête contient la valeur ACK. Le champ séquence contient la valeur 51, c'est-à-dire le numéro du prochain octet qui a l'intention envoyer TCP. Lorsque TCP envoie les données suivantes, le nouvel en-tête TCP aura également une valeur de 51 dans le champ de séquence.

10.4 Établir une connexion

Comment les deux applications se connectent-elles ? Avant la communication, chacun d'eux appelle un sous-programme pour former un bloc de mémoire qui servira à stocker les paramètres TCP et IP de cette connexion, par exemple, les adresses de socket, le numéro de séquence courant, la valeur initiale de la durée de vie, etc.

L'application serveur attend l'apparition d'un client qui, voulant accéder au serveur, émet une demande de composé(connecter) identifiant l'adresse IP et le port du serveur.

Il y a une particularité technique. Chaque côté commence la numérotation de chaque octet non pas par un, mais par numéro de séquence aléatoire(nous découvrirons plus tard pourquoi cela est fait). La spécification d'origine conseille de générer un numéro de séquence initial basé sur un temporisateur externe de 32 bits qui s'incrémente environ toutes les 4 s.

10.4.1 Script de connexion

La procédure de connexion est souvent appelée poignée de main à trois car trois messages sont échangés — SYN, SYN et ACK — pour établir une connexion.

Lors de la configuration de la connexion, les partenaires échangent trois informations importantes :

1. La quantité d'espace tampon pour recevoir des données

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

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

A noter que chacune des parties applique les opérations 1 et 2 pour indiquer les limites dans lesquelles l'autre partie opérera. Un ordinateur personnel peut avoir une petite mémoire tampon de réception, et un superordinateur peut avoir une énorme mémoire tampon. La structure de mémoire d'un ordinateur personnel peut limiter les portions de données entrantes à 1 Ko, et le superordinateur est contrôlé avec de grands segments.

La possibilité de contrôler la manière dont l'autre partie envoie des données est une propriété importante pour l'évolutivité TCP/IP.

En figue. 10.8 montre un exemple de script de connexion. Des numéros séquentiels initiaux très simples sont présentés pour ne pas surcharger le dessin. Notez que dans cette figure, le client est capable de recevoir des segments plus gros que le serveur.


Riz. 10.8.Établir une connexion

Les opérations suivantes sont effectuées :

1. Le serveur est initialisé et devient prêt à se connecter aux clients (cet état est appelé 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 (dans cet exemple - 1000) et envoie segment de synchronisation(synchroniser le segment - SYN). Ce segment porte le numéro de séquence, la taille de la fenêtre de réception (4 Ko) et le plus grand segment que le client peut accepter (1460 octets).

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 un numéro de séquence de départ (3000), ACK 1001 (ce qui signifie que le premier octet envoyé par le client est numéroté 1001), la taille de la fenêtre de réception (4K) et le plus grand segment que le serveur peut recevoir (1024 octets ).

5. Le client TCP, ayant reçu le 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 de l'ouverture de la connexion.

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 réussi), lorsque des applications homologues s'ouvrent simultanément activement.

10.4.2 Réglage des valeurs des paramètres IP

La demande de connexion de l'application peut également spécifier des paramètres pour les datagrammes IP qui transporteront les données pour cette 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 sélectionner 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, théoriquement, ces valeurs peuvent 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 utilisées pour chaque sens d'échange.

Lorsqu'une application utilise des options de sécurité pour les agences gouvernementales ou militaires, chacun des points de terminaison de connexion doit utiliser les mêmes niveaux de sécurité, sinon la connexion ne sera pas établie.

10.5 Transfert de données

Le transfert de données commence après l'achèvement de la confirmation en trois étapes de la création de la connexion (voir Fig. 10.9). La norme TCP permet d'inclure des données normales dans des segments d'accusé de réception, mais elles ne seront pas transmises à l'application tant que la connexion n'est pas terminée. Pour faciliter la numérotation, des messages de 1 000 octets sont utilisés. Chaque segment d'en-tête TCP a un champ ACK qui identifie le numéro de séquence de l'octet qui devrait être reçu de l'homologue sur la 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 une valeur de 3001, qui indique le numéro de séquence de l'octet qui est censé être reçu du serveur.

Le serveur répond au client avec un segment contenant 1000 octets de données (à partir de 3001). Son champ ACK d'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 devrait être 2001.

Le client envoie ensuite des segments commençant par les octets 2001, 3001 et 4001 dans cet ordre. Notez que le client ne s'attend pas à un ACK après chacun des segments envoyés. Les données sont envoyées au partenaire jusqu'à ce que son espace tampon soit plein (nous verrons plus loin que le destinataire peut indiquer très précisément la quantité de données qui lui sont envoyées).

Le serveur conserve la bande passante en utilisant un seul ACK pour indiquer le transfert réussi de tous les segments.

En figue. 10.10 montre le transfert de données lorsque le premier segment est perdu. Lorsque le délai expire, le segment est retransmis. Notez qu'à la réception du segment perdu, le récepteur envoie un ACK confirmant que les deux segments ont été envoyés.


Riz. 10.10. Perte et retransmission de données

10.6 Fermeture d'une connexion

La terminaison normale d'une connexion s'effectue en utilisant la même procédure de triple poignée de main que lors de l'ouverture d'une connexion. Chacune des parties peut commencer à fermer la connexion dans le scénario suivant :

UNE:

B :"Bon".

V :"J'ai fini le travail aussi."

UNE:"Bon".

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

UNE:« J'ai terminé. Il n'y a plus de données à envoyer. »

V :"Bien. Cependant, il y a quelques données ..."

V :"J'ai fini le travail aussi."

UNE:"Bon".

Dans l'exemple ci-dessous, la connexion ferme le serveur, comme c'est souvent le cas pour les communications client/serveur. Dans ce cas, après l'entrée de l'utilisateur dans la session telnet commandes de déconnexion, le serveur lance une demande de fermeture de la connexion. Dans la situation illustrée à la Fig. 10.11, les actions suivantes sont effectuées :

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

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

3. Le TCP du client 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 cliente dit à son TCP de fermer la connexion.

6. Le TCP du client envoie un message FIN.

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

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


Riz. 10.11. Fermeture d'une connexion

Les deux côtés peuvent commencer à fermer en même temps. Dans ce cas, la fermeture normale de la connexion est terminée après que chaque partenaire a envoyé un message ACK.

10.6.1 Résiliation brutale

Chacune des parties peut demander une fermeture brutale de la connexion. Ceci est acceptable lorsqu'une application souhaite mettre fin à une connexion ou lorsque TCP rencontre un problème de communication sérieux qu'il ne peut pas résoudre seul. Une terminaison brutale est demandée en envoyant un ou plusieurs messages de réinitialisation à l'homologue, 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 recevoir. Cette limitation affecte l'expéditeur TCP. L'explication ci-dessous de ce mécanisme est conceptuelle et les développeurs peuvent l'implémenter de différentes manières dans leurs produits.

Lors de l'établissement de la connexion, chaque partenaire alloue de l'espace pour le tampon d'entrée de la connexion et en informe l'autre côté. Typiquement, 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é avant d'être envoyé à l'application (déterminé par le port TCP). En figue. 10.12 montre un tampon d'entrée capable d'accepter 4 Ko.


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

L'espace tampon se remplit à mesure que les données arrivent. Lorsque l'application réceptrice récupère les données du 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 non encore occupé par des données. Les données restent dans la mémoire tampon d'entrée jusqu'à ce qu'elles soient consommées par l'application cible. Pourquoi l'application ne récupère-t-elle pas les données tout de suite ?

Un scénario simple aidera à répondre à cette question. Supposons qu'un client ait téléchargé un fichier sur un serveur FTP s'exécutant sur un ordinateur multi-utilisateurs très occupé. Le programme FTP doit ensuite lire les données du tampon et les écrire sur le disque. Lorsque le serveur effectue des opérations d'E/S sur disque, le programme attend la fin de ces opérations. A ce moment, un autre programme peut démarrer (par exemple, selon un planning) et pendant que le programme FTP redémarre, les données suivantes arriveront déjà dans la mémoire tampon.

La fenêtre de réception s'étend du dernier octet acquitté à la fin du tampon. En figue. 10.12 tout d'abord, la totalité du tampon est disponible et donc une fenêtre de réception de 4 Ko est disponible. Lorsque le premier Ko arrive, la fenêtre de réception sera réduite à 3 Ko (pour simplifier, nous supposerons que chaque segment fait 1 Ko, bien qu'en pratique cette valeur varie en fonction des besoins de l'application). L'arrivée des deux prochains segments de 1 Ko réduira la fenêtre de réception à 1 Ko.

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 depuis la source est régulé.

Pour la plupart, la taille du tampon d'entrée est définie au démarrage de la connexion, bien que la norme TCP ne spécifie 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 n'est pas arrivé dans l'ordre ? Il est généralement supposé que toutes les implémentations stockent les données reçues dans la fenêtre de réception et envoient un accusé de réception (ACK) uniquement pour un bloc contigu entier de plusieurs segments. Il s'agit de la bonne méthode, car sinon la suppression des données dans le désordre dégradera considérablement les performances.

10.7.2 Fenêtre de soumission

Le système transmettant les données doit garder une trace de deux caractéristiques : combien de données ont déjà été envoyées et acquittées, et la taille actuelle de la fenêtre de réception du destinataire. actif espace d'expédition(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é par envoyer, indique combien de données supplémentaires peuvent être envoyées au partenaire.

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

1. L'expéditeur commence par 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 les retransmettre.

3. Le message ACK pour le premier Ko arrive et les 2 Ko suivants de données 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 à 4K.

Riz. 10.13. Fenêtre d'envoi

Il convient de souligner plusieurs caractéristiques intéressantes :

S L'expéditeur n'attend pas d'ACK pour chacun des segments de données qu'il envoie. La seule limitation de transfert est la taille de la fenêtre de réception (par exemple, l'expéditeur ne doit envoyer que des segments à un octet de 4K).

■ 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

En figue. 10.14 montre le format du segment (en-tête et données TCP). L'en-tête commence par les ID de port source et de destination. Champ suivant suivant numéro de série(numéro de séquence) indique la position dans le flux de données sortant qu'occupe ce segment. Champ ACK(accusé de réception) contient des informations sur le prochain segment attendu à apparaître dans le flux de données d'entrée.


Riz. 10.14. segment TCP

Il y a six drapeaux :

Champ biais 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 à une limite de 32 bits.

10.8.1 Option pour la taille maximale du segment

Paramètre "taille maximale des segments"(taille maximale de segment - MSS) est utilisé pour annoncer le plus gros morceau de données pouvant être reçu et traité 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. mais taille maximale des segments défini comme:

Le plus grand datagramme que vous pouvez accepter est 40

En d'autres termes, le MSS reflète la plus grande charge utile dans le récepteur avec une longueur d'en-têtes TCP et IP 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ée dans un segment est définie comme :

Valeur déclarée MSS + 40 - (somme des longueurs des en-têtes 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 de valeur de taille de segment maximale, la valeur par défaut de 536 octets est utilisée.

La taille du segment maximum est codée avec un préambule de 2 octets suivi d'une valeur de 2 octets, c'est-à-dire la plus grande valeur sera 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 plus petite, puisque la MTU le long du chemin 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 est de 536 octets) que TCP s'attend à recevoir. Cette valeur a une longueur de 32 bits et est généralement présente dans la demande de connexion dans le champ options(Option). L'en-tête TCP contenant la valeur MSS fait 24 octets.

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

Dans une réponse d'activation à une demande de connexion, les deux drapeaux (SYN et ACK) sont égaux à 1. Le système répondant indique le numéro de séquence initial 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 à la demande de connexion (dans le options). Cette valeur peut être différente de la valeur du demandeur de 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 du numéro de séquence de départ

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

Imaginez ce qui se passe lorsque le système tombe en panne. Supposons que l'utilisateur ouvre une connexion juste avant le crash et envoie une petite quantité de données. Après la récupération, le système ne se souvient plus de rien de 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 effondrement et que son travail a ensuite été restauré. Tout cela entraînera de graves interruptions de travail, en particulier lorsqu'il faut beaucoup de temps avant que les anciennes données ne circulent sur le réseau et se mélangent aux données de la connexion nouvellement créée. La sélection de la minuterie du nouveau départ élimine ces problèmes. Les anciennes données seront numérotées différemment de la plage de numéros de séquence de la nouvelle connexion. Les pirates, lorsqu'ils falsifient l'adresse IP source d'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 est le meilleur moyen de sélectionner des numéros de départ sécurisé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 nombre séquentiel(Numéro de séquence).

Le prochain numéro d'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 actuelle de la fenêtre de réception. Ce champ contient le nombre d'octets du numéro de confirmation qui peuvent être acceptés... Notez que cette valeur permet un contrôle précis sur le flux de données. A l'aide de cette valeur, le partenaire indique l'état réel de la fenêtre de réception pendant la session d'échange.

Si l'application pointe vers une opération TCP push, 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 veut les envoyer.

Le fanion URGENT, s'il est mis à 1, implique un transfert de données urgentes, et le pointeur correspondant DOIT se référer au dernier octet de données urgentes. Une utilisation typique des données urgentes consiste à envoyer des signaux d'annulation ou d'interruption à partir du terminal.

Les données urgentes sont souvent appelées informations hors bande(hors bande). Cependant, ce terme est inexact. Les données expédiées sont envoyées sur un flux TCP régulier, bien que certaines implémentations puissent avoir des mécanismes spéciaux pour dire à l'application de recevoir des données urgentes, et l'application doit vérifier le contenu des données urgentes avant que tous les octets du message n'arrivent.

L'indicateur RESET est mis à 1 pour annuler la connexion. Le même indicateur est défini dans la réponse lorsqu'un segment arrive qui n'est associé à aucune des connexions TCP actuelles.

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 est pour l'en-tête IP uniquement, et la somme de contrôle TCP est calculée pour le segment entier 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. 10.15 montre un pseudo-en-tête très similaire à celui utilisé dans la somme de contrôle UDP.


Riz. 10.15. Le champ pseudo-en-tête est 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 UDP. La somme de contrôle du segment reçu 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 supprimé.

10.9 Exemple de segment TCP

Riz. 10.16, protocole de l'analyseur renifleur par Network General, est une séquence de segments TCP. Les trois premiers segments établissent une connexion entre le client et le serveur Telnet... Le dernier segment contient 12 octets de données.


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

Analyseur renifleur traduit la plupart des valeurs en décimal. Cependant, les valeurs des drapeaux sont sorties en hexadécimal. Le drapeau avec la valeur 12 est 010010. La somme de contrôle est également affichée en hexadécimal.

10.10 Prise en charge des séances

10.10.1 Sondage de fenêtre

Un émetteur rapide et un récepteur lent peuvent former une fenêtre de réception de 0 octet. Ce résultat est appelé fermer la 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 minuterie enregistrée(minuterie persistante) lorsque la fenêtre est fermée. La valeur du temporisateur est le délai d'attente de retransmission. A la fin du timer, un segment est envoyé au partenaire fenêtre de sondage(sonde de fenêtre ; certaines implémentations incluent également des données). La vérification amène l'homologue à renvoyer un ACK qui signale l'état actuel de la fenêtre.

Si la fenêtre est toujours de taille nulle, la valeur du temporisateur stocké est doublée. Ce processus est répété jusqu'à ce que la minuterie atteigne un maximum de 60 secondes. TCP continuera à envoyer des messages de sonde toutes les 60 secondes - jusqu'à ce que la fenêtre soit ouverte, jusqu'à ce que l'utilisateur termine le processus ou jusqu'à ce que l'application expire.

10.11 Déconnexion

10.11.1 Délai d'attente

Le partenaire de connexion peut tomber en panne ou être complètement interrompu en raison d'une passerelle ou d'une panne de communication. Il existe plusieurs mécanismes pour empêcher TCP de renvoyer des données.

Une fois le premier seuil de retransmission (relayage) atteint, TCP demande à IP de vérifier 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 ce n'est qu'alors qu'il met fin à la connexion.

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

L'application peut définir son propre délai de livraison de données et effectuer ses propres opérations à la fin de cet intervalle. La connexion est généralement déconnectée.

10.11.2 Maintien de la connexion

Lorsqu'une connexion incomplète a des données à transférer pendant une longue période, elle obtient le statut inactif. Pendant une période d'inactivité, un plantage du réseau ou une perte de liens physiques 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 était conforme aux exigences du ministère de la Défense.

Cependant, toute connexion - active ou inactive - occupe 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 garder la connexion(keep-alive) teste les connexions inactives. De tels messages sont périodiquement envoyés au partenaire pour vérifier son existence sur le réseau. Les messages ACK doivent être reçus en réponse. L'utilisation de messages keepalive est facultative. Si le système dispose de cette capacité, l'application peut l'annuler par ses propres moyens. Période estimée défaut le délai d'attente pour maintenir une connexion est de deux heures complètes !

Rappelons que l'application peut définir son propre timer, selon lequel, à son propre niveau, elle prendra une décision sur la fin de la connexion.

10.12 Performance

Quelle est l'efficacité de TCP ? De nombreux facteurs affectent les performances des ressources, dont la mémoire et la bande passante sont les principaux (voir Figure 10.17).


Riz. 10.17. Facteurs de performance TCP

La bande passante et la latence du réseau physique utilisé limiteront considérablement la bande passante. Une mauvaise qualité de transfert de données entraîne un volume important de datagrammes abandonnés, ce qui provoque une retransmission et, par conséquent, réduit l'efficacité de la bande passante.

Le côté récepteur doit fournir un espace tampon suffisant pour permettre à l'expéditeur de transférer des données sans interruption. Ceci est particulièrement important pour les réseaux à latence élevée, où il y a un long intervalle de temps entre l'envoi de données et la réception d'un ACK (et également lors de la négociation de la taille de la fenêtre). Pour maintenir un flux de données stable depuis la source, le côté récepteur doit avoir une fenêtre d'au moins la bande passante multipliée par le produit de retard.

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, alors de l'autre côté il faut prévoir une fenêtre de réception d'au moins 20 000 octets, sinon le flux de données ne sera pas continue. Un tampon de réception de 10 000 octets réduira le débit de moitié.

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

Les ressources du CPU de l'ordinateur sont nécessaires au traitement des en-têtes TCP. Si le processeur est incapable de calculer rapidement les sommes de contrôle, il ralentira le taux de transfert des données sur le réseau.

En outre, les développeurs doivent envisager de simplifier la configuration des paramètres TCP afin que l'administrateur réseau puisse les personnaliser en fonction de leurs exigences locales. 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 : les ressources sont suffisantes et le changement de contexte est plus rapide que les cow-boys sortant leurs revolvers. Obtiendrez-vous d'excellentes performances ?

Pas toujours. La qualité du développement du logiciel TCP est également importante. De nombreux problèmes de performances ont été diagnostiqués et résolus au fil des ans dans diverses implémentations TCP. Le meilleur logiciel est la RFC 1122, qui définit les exigences de la couche de communication pour les hôtes Internet.

L'exception est 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 récolter des avantages significatifs en créant des programmes qui éliminent les transferts inutiles de petites quantités de données 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 à la partie plutôt complexe de TCP, nous examinerons les mécanismes permettant d'améliorer les performances et de résoudre les goulots d'étranglement de la bande passante. Cette section aborde les questions suivantes :

Démarrage lent(démarrage lent) empêche une grande partie du trafic réseau d'être utilisée pour une nouvelle session, ce qui peut entraîner une surcharge.

■ Récupération de syndrome de la fenêtre loufoque(silly window syndrome) empêche les applications mal conçues de surcharger le réseau avec des messages.

ACK retardé(ACK retardé) réduit l'encombrement en réduisant le nombre de messages d'accusé de réception avant indépendants.

Délai de retransmission calculé(calcul du délai d'expiration de la retransmission) est basé sur la négociation de la durée de session en temps réel, réduisant les retransmissions inutiles, mais n'entraînant pas de retards importants pour les échanges de données réellement nécessaires.

■ Ralentissez le 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.

■ Envoi ACK dupliqués(ACK en double) lors de la réception d'un segment hors séquence, permet aux pairs de renvoyer avant l'expiration du délai.

10.13.1 Démarrage lent

Si tous les appareils électroménagers sont allumés en même temps à la maison, une surcharge du réseau électrique se produira. Dans les réseaux informatiques démarrage lent empêche les fusibles secteur de sauter.

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

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

Notez que le démarrage lent n'est pas si lent. Après le premier ACK, la taille de la fenêtre de chargement est égale à 2 segments, et après avoir reçu avec succès un ACK 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élai d'attente se soit produite. Le comportement de la fenêtre de chargement dans ce cas est décrit ci-dessous.

10.13.2 Syndrome de la fenêtre sans idée

Dans les premières implémentations de TCP/IP, les développeurs ont été confrontés au phénomène syndrome de la fenêtre loufoque(Silly Window Syndrome - SWS), qui est apparu assez souvent. Pour comprendre les événements qui se déroulent, considérons le scénario suivant, qui entraîne des conséquences indésirables, mais il est tout à fait possible :

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

2. L'application réceptrice lit 1 octet de données dans le 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 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 de réception envoie un ACK signifiant "Merci. J'ai reçu un paquet et je n'ai plus d'espace libre."

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

Une application à 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 de la vie réelle, bien sûr, ne sont pas si extrêmes. Un expéditeur rapide et un récepteur lent échangeront de petits morceaux de données (par rapport à la taille maximale du segment) et basculeront sur une fenêtre de réception presque complète. En figue. 10.18 montre les conditions d'apparition du syndrome de la "fenêtre maladroite".


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

Ce problème n'est pas difficile à résoudre. Dès que la fenêtre de réception se réduit moins que la taille cible donnée, TCP commence à tromper l'expéditeur. Dans cette situation, TCP ne doit pas diriger l'expéditeur vers Additionnel espace dans la fenêtre lorsque l'application réceptrice lit les données du tampon en 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. La taille recommandée est d'un segment, à moins que la totalité du tampon d'entrée ne contienne un seul segment (dans ce dernier cas, une taille égale à la moitié du tampon est utilisée). La taille cible à signaler par TCP peut être exprimée comme suit :

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

TCP commence à tricher lorsque la taille de la fenêtre devient inférieure à cette taille et dira la vérité lorsque la taille de la fenêtre n'est pas inférieure à la valeur obtenue par la formule. Notez qu'il n'y a pas de préjudice pour l'expéditeur car l'application réceptrice ne serait toujours pas en mesure de traiter la plupart des données qu'elle attend.

La solution proposée peut être facilement vérifiée dans le cas ci-dessus avec une sortie ACK pour chacun des octets reçus. La même méthode convient également au cas où le buffer d'entrée peut stocker plusieurs segments (comme c'est souvent le cas en pratique). L'expéditeur rapide remplira le tampon d'entrée, mais le récepteur 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, exclure le transfert de 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 de pousser) en attendant l'ACK des données précédemment transmises. Les données accumulées sont envoyées après avoir reçu un ACK sur une information précédemment envoyée, ou après avoir reçu des données pour l'envoi de la taille d'un segment complet, ou après l'expiration du délai d'attente. Cet algorithme ne doit pas être utilisé pour des applications en temps réel qui doivent envoyer des données le plus rapidement possible.

10.13.4 ACK retardé

Un autre mécanisme d'amélioration des performances est la méthode de délai ACK. La réduction du nombre d'ACK réduit la quantité de bande passante pouvant être utilisée pour transférer d'autres trafics. Si l'homologue TCP retarde légèrement l'envoi de l'ACK, alors :

■ Vous pouvez accuser réception de plusieurs segments avec un seul ACK.

■ L'application réceptrice est capable de recevoir une certaine quantité de données dans l'intervalle de temporisation ; l'en-tête de sortie peut être inclus dans l'ACK, et il ne nécessite pas la formation d'un message séparé.

Afin d'éviter les retards lors de l'envoi d'un flux de segments complets (par exemple, lors de l'échange de fichiers), un ACK doit être envoyé au moins pour chaque deuxième segment complet.

De nombreuses implémentations utilisent un délai d'attente de 200 ms. Mais l'ACK retardé ne ralentit pas le taux de change. Lorsqu'un segment court arrive, il reste suffisamment d'espace libre dans le tampon d'entrée pour recevoir de nouvelles données et l'expéditeur peut continuer à envoyer (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 dans la même seconde.

10.13.5 Délai de retransmission

Après avoir envoyé le segment, TCP définit un temporisateur et surveille l'arrivée de l'ACK. Si aucun ACK n'est reçu dans le délai d'attente, TCP retransmet le segment (relais). Cependant, quel devrait être le délai d'attente?

S'il est trop court, l'expéditeur remplira le réseau de segments de transfert inutiles qui dupliqueraient les informations déjà envoyées. Un timeout trop long vous empêchera de réparer rapidement les segments qui sont vraiment mauvais pendant le transfert, ce qui réduira le débit.

Comment choisir le bon intervalle de timeout ? Une valeur qui est bonne pour un réseau local à haut débit n'est pas bonne pour une connexion distante à plusieurs coups. Cela signifie que 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 délais 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 couvrirons brièvement ci-dessous.

Le bon sens dicte que la meilleure base pour estimer le délai d'expiration correct pour une connexion particulière peut être 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.

De bonnes décisions pour les quantités suivantes peuvent être obtenues à partir de statistiques de base (voir Figure 10.19) qui peuvent vous aider à calculer les temps d'attente. Cependant, il n'est pas nécessaire de se fier aux moyennes, car plus de la moitié des estimations seront supérieures à la moyenne. En examinant quelques écarts, vous pouvez obtenir des estimations plus correctes, en tenant compte de la distribution normale et en réduisant le temps d'attente trop long pour la retransmission.


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. Des estimations approximatives peuvent être utilisées sur la base de la valeur absolue de la différence entre la dernière valeur et l'estimation moyenne :

Dernier écart = | Dernier cycle - Moyenne |

Un autre facteur à prendre en compte dans le calcul de la valeur de temporisation correcte est le changement de temps de cycle dû aux conditions actuelles du réseau. Ce qui s'est passé sur le web à la dernière minute est plus important que ce qui s'est passé il y a une heure.

Supposons que vous calculiez une moyenne de cycle pour une très longue session. Même si le réseau était initialement peu chargé et que nous ayons déterminé 1 000 petites valeurs, il y a eu une augmentation du trafic avec une augmentation significative de la latence.

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

170 × 1000/1050 + 282 × 50/1050 = 175

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

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

La valeur est comprise entre 0 et 1. Augmenter un entraîne une plus grande influence du temps de cycle actuel sur la moyenne lissée. Étant donné que les ordinateurs peuvent diviser rapidement par des puissances de 2 en déplaçant les nombres binaires vers la droite, α est toujours choisi pour être (1/2) n (généralement 1/8), donc :

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

Le tableau 10.2 montre comment la formule de SRTT s'ajuste à la valeur actuelle de SRTT de 230 lorsqu'un changement dans l'état du réseau entraîne une augmentation progressive du temps de cycle (en supposant qu'aucun délai d'attente 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 comme l'ancien SRTT).


Tableau 10.2 Calcul du temps de cycle lissé

Ancien SRTT RTT le plus récent (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, il y a une question sur le choix d'une valeur pour le délai de retransmission. L'analyse des temps de cycle montre un écart important de ces valeurs par rapport à la moyenne actuelle. Il est logique de fixer une limite pour l'ampleur des écarts (écarts). Les bonnes valeurs de timeout de retransmission (appelées Retransmission TimeOut - RTO dans les normes RFC) sont données par la formule suivante avec une contrainte de déviation lissée (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 |

La formule de lissage est ensuite utilisée pour tenir compte de la dernière valeur :

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

Une question demeure : quelles sont les valeurs initiales ? Conseillé:

Temporisation initiale = 3 s

SRTT initial = 0

SDEV initial = 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 ? Lorsque cette valeur a été atteinte, des améliorations significatives des performances ont été observées. Un exemple serait les statistiques d'équipe netstat reçu sur le système tigre- un serveur Internet accessible par de nombreux hébergeurs 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 messages ACK), seulement 0,6 % a été dupliqué. Il faut garder à l'esprit que le niveau de perte des 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 resoumission

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 ne soit reçu pendant la période de temporisation et que les données doivent être renvoyées.

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

10.13.8 Actions après retransmission

Mais que se passe-t-il avant que la confirmation ne soit reçue ? Après la 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 :

■ Réduction de la vitesse de réexpédition

■ Réduire la congestion du réseau en réduisant le trafic global

10.13.9 Freinage exponentiel

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

Si la panne de courant persiste, la période de temporisation doublera jusqu'à ce que la valeur maximale prédéfinie (généralement 1 minute) soit atteinte. Un seul segment peut être envoyé après le délai d'attente. La temporisation se produit également lorsque la valeur prédéterminée du nombre de transferts de données sans recevoir d'ACK est dépassée.

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

La réduction de la quantité de données transférées est un peu plus complexe que les mécanismes décrits ci-dessus. Cela commence à fonctionner, comme le démarrage lent déjà mentionné. Mais, étant donné qu'une limite est définie pour le niveau de trafic, ce qui peut entraîner des problèmes au début, le taux de change ralentira en fait en raison d'une augmentation de la taille de la fenêtre de charge pour un segment. Vous devez définir des valeurs de bordure pour vraiment réduire la vitesse de téléchargement. 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 obtenue est supérieure à deux segments, elle est utilisée comme limite. Sinon, la bordure est définie sur deux segments. Un 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 un mécanisme de démarrage lent).

S Ensuite, avec chaque ACK reçu, ajoutez une valeur plus petite à la fenêtre de charge, qui est sélectionnée 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 charge fenêtre en segments).

Un scénario idéal pourrait simplifier le travail du mécanisme de récupération. Supposons que la fenêtre de réception du partenaire (et la fenêtre de chargement actuelle) ait une taille de 8 segments avant que le délai d'expiration ne soit détecté et que la limite soit définie comme 4 segments. Si l'application réceptrice lit instantanément les données du tampon, 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).

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

■ ACK reçu 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 l'accusé de réception de toutes les données envoyées est requis 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 déroulent sont illustrés à la Fig. 10.20. La taille de la fenêtre augmente de façon exponentielle, doublant pendant la période de démarrage lent, et une fois la limite atteinte, elle augmente linéairement.


Riz. 10.20. Limiter le taux de transfert pendant la congestion

10.13.11 ACK en double

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 à l'envoi d'ACK supplémentaires par le récepteur, indiquant une lacune dans les données reçues.

Recevant un segment en panne, le récepteur renvoie un ACK pointant sur le premier octet perdu données (voir la figure 10.21).


Riz. 10.21. ACK dupliqués

L'expéditeur ne retransmet pas instantanément les données car IP peut normalement fournir des données au destinataire sans séquence d'envoi. Mais lorsque plusieurs ACK supplémentaires pour les données en double sont reçus (par exemple, trois), le segment manquant sera envoyé sans attendre l'expiration du délai d'expiration.

Notez que chaque ACK en double indique la réception d'un segment de données. Quelques ACK en double vous permettent de savoir que le réseau est capable de fournir suffisamment de données et n'est donc pas surchargé. 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 réelle augmentation du trafic réseau. Dans ce cas, le processus de redimensionnement radical lors de la restauration des travaux 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 (extinction de la source). Cependant, le signaler n'est pas ciblé ou efficace car la connexion recevant ce message peut ne pas générer trop de trafic. Spécification actuelle Exigences du routeur(exigences du routeur) indique que les routeurs ne devrait pas envoyer des messages sur la suppression de la source.

10.13.13 Statistiques TCP

Enfin, regardons les messages statistiques de la commande netstat, de voir à l'œuvre bon nombre des mécanismes décrits ci-dessus.

Les segments sont nommés packages.
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)
On note un grand nombre de

ACK retardé.

Sonder l'ouverture de la fenêtre

taille zéro.

Ce sont des messages SYN et FIN.
762469 ack (pour 226904227 octets)
Alerte colis arrivant

Hors de la séquence.

1510769 paquets (314955304 octets)
9006 paquets complètement dupliqués (867042 octets)
Le résultat du délai d'attente lorsqu'il est réel

livraison de données.

74 paquets avec du dup. données (12193 octets dupés)
Pour plus d'efficacité

certaines données ont été reconditionnées pour inclure des octets supplémentaires lorsqu'elles ont été soumises à nouveau.

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

inclus dans les messages de détection.

402 paquets reçus après fermeture
Ce sont les rediffusions de suivi

Envoi en cours.

108 rejetés pour de 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 gouttes)
4100 connexions embryonnaires abandonnées
572187 segments mis à jour rtt (sur 587397 tentatives)
Tentatives de modification infructueuses

le temps de cycle, car l'ACK n'a pas eu le temps d'arriver avant l'expiration du timeout,

26 connexions abandonnées par le délai d'expiration de la réémission
Tentatives ultérieures infructueuses

ré-envoi, ce qui indique une connexion perdue.

Délais de vérification

fenêtre zéro.

Délais de paiement

connexion rompue.

472 connexions abandonnées par keepalive

10.14 Conformité aux exigences du développeur

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

Que se passe-t-il si vous installez un système qui ne respecte pas ces normes ? Il ne sera pas en mesure de fournir des performances adéquates à 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 congestion temporaire et créant un trafic excessif entraînant la perte de datagrammes.

10.15 Obstacles à la performance

TCP a prouvé sa flexibilité, fonctionnant sur des réseaux avec des taux d'échange de centaines ou de millions de bits par seconde. Ce protocole a permis d'obtenir de bons résultats dans les réseaux locaux modernes avec des topologies Ethernet, Token-Ring et Fiber Distributed Data Interface (FDDI), ainsi que pour les lignes de communication à bas débit ou les connexions longue distance (comme les liaisons satellites) .

TCP est conçu pour répondre à des conditions extrêmes telles que la congestion du réseau. Cependant, la version actuelle du protocole présente des fonctionnalités qui limitent les performances des technologies prometteuses qui offrent des bandes passantes de centaines et de milliers de mégaoctets. Pour comprendre les problèmes qui se posent, considérons un exemple simple (bien qu'irréaliste).

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

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

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

La bande passante permet d'envoyer deux segments en 1 seconde.

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

Les messages S ACK arrivent en 2 secondes.

L'expéditeur est capable d'envoyer des données en continu. Après tout, lorsque le volume alloué pour la fenêtre est plein, un ACK arrive, permettant l'envoi d'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 encore 2 s :

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

Si la fenêtre de réception n'était que de 2 Ko, 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 nombres plus simples), la petite fenêtre peut entraîner des problèmes avec les connexions satellites à 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 millions de bits par seconde, mais que le temps de cycle est de 100 ms (1/10ème de seconde), alors pour un flux continu, la fenêtre de réception doit stocker au moins 1 000 000 bits, c'est-à-dire... 125 000 octets. Mais le plus grand nombre pouvant être écrit dans le champ d'en-tête pour une fenêtre de réception TCP est 65 536.

Un autre problème se pose à des débits en bauds élevés, car les numéros de séquence s'épuisent très rapidement. Si la connexion peut transférer des données à une vitesse de 4 Go / s, les numéros de séquence doivent être mis à jour toutes les secondes. Il ne sera pas possible de faire la distinction entre les anciens datagrammes en double qui ont été retardés de plus d'une seconde lors de leur déplacement sur Internet à partir de nouvelles données récentes.

De nouvelles recherches sont en cours pour améliorer TCP/IP et supprimer les barrières ci-dessus.

10.16 Fonctions TCP

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

■ Liaison des ports aux connexions

■ Initialisation des connexions par confirmation en 3 étapes

■ Effectue 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 des sommes de contrôle

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

■ Terminaison de la connexion de la manière établie

■ Terminer la connexion

■ Transmission de données urgentes

■ Confirmation positive de réexpédition

■ Calcul du délai de retransmission

■ Trafic de retour réduit en cas de congestion du réseau

■ Alarme d'arrivée de segment en panne

■ Détection de la fermeture de la fenêtre de réception

10.17 États TCP

Une connexion TCP passe par plusieurs étapes : la connexion est établie par l'échange de messages, puis les données sont envoyées, puis la connexion est fermée à l'aide de l'échange de messages spéciaux. Chaque étape du travail de la connexion correspond à un certain état 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 une transition d'état typique du serveur et du client situés à différentes extrémités de la connexion. Nous n'avons pas l'intention de donner une description exhaustive de tous les états possibles lors du transfert de données. Il se trouve 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 indiqués dans le Tableau 10.3 et les états des clients sont indiqués dans le Tableau 10.4.


Tableau 10.3 Séquence d'état du serveur

État du serveur Événement La description
FERMÉ (fermé) Un état fictif avant de démarrer une connexion.
Ouverture passive par application serveur.
ÉCOUTER (suivi) Le serveur attend une connexion client.
Le serveur TCP reçoit un SYN et envoie un SYN/ACK. Le serveur a reçu un SYN et envoyé un SYN / ACK. Va attendre ACK.
SYN-REÇU Le serveur TCP reçoit l'ACK.
ÉTABLI (installé) ACK reçu, connexion ouverte.

Tableau 10.4 Séquence d'état du client

Si les partenaires essayaient simultanément de se connecter les uns aux autres (ce qui est extrêmement rare), chacun passerait par les états CLOSED, SYN-SENT, SYN-RECEIVED et ESTABLISHED.

Les extrémités de la connexion restent dans l'état ESTABLISHED jusqu'à ce que l'un des côtés initie fermeture connexions en envoyant un segment FIN. Lors d'une fermeture normale, la partie qui initie cette fermeture passe par les états indiqués dans le Tableau 10.5. Son partenaire passe par les états indiqués dans le tableau 10.6.


Tableau 10.5 Séquence d'état de la partie fermant la connexion

États latéraux de fermeture Événement La description
ÉTABLI L'application locale demande la fermeture de la connexion.
TCP envoie FIN/ACK.
FIN-ATTENDRE-1 La partie de couverture 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 Le côté de fermeture a reçu un ACK du partenaire, mais le FIN n'est pas encore arrivé. Le côté de fermeture attend un FIN, acceptant les données entrantes.
TCP reçoit FIN/ACK.
Envoie ACK.
TEMPS D'ATTENTE La connexion est maintenue dans un état indéterminé pour permettre aux données en double ou aux FINs en double qui existent encore sur le réseau d'arriver ou de se retirer. La période d'attente est le double de l'estimation de la durée de vie maximale du segment.
FERMÉ

Tableau 10.6 Séquence d'états partenaires pour fermer une connexion

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

10.17.1 Analyse des états de connexion TCP

Commander netstat -an permet de vérifier l'état actuel de la connexion. Les connexions dans les états sont indiquées ci-dessous é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 locale et externe. Vous pouvez voir qu'il y a du 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 Notes de mise en œuvre

Dès le début, le protocole TCP a été conçu pour interopérer des équipements réseau de différents fabricants. La spécification TCP ne spécifie pas exactement comment les structures de mise en œuvre internes doivent fonctionner. Ces questions sont laissées aux développeurs pour trouver les meilleurs mécanismes pour chaque implémentation spécifique.

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 y a parfois des produits qui n'implémentent pas les exigences MUST. En conséquence, les utilisateurs subissent une dégradation des performances.

Certaines bonnes pratiques de mise en œuvre ne sont pas prises en compte dans les normes. Par exemple, il est possible d'améliorer la sécurité en limitant l'utilisation de ports connus par des processus système privilégiés si cette méthode est prise en charge sur le système d'exploitation local. Pour améliorer les performances, les implémentations doivent avoir le moins possible de copies et de déplacements de données envoyées ou récupérées.

API standard indéfini(ainsi que la politique de sécurité) afin qu'il y ait un champ libre pour expérimenter différents ensembles d'outils logiciels. Cependant, cela peut entraîner l'utilisation de différentes API sur chaque plate-forme et empêcher le logiciel d'application d'être déplacé entre les plates-formes.

En fait, les développeurs basent leurs boîtes à outils sur une API Socket empruntée à Berkeley. L'importance de l'interface de programmation s'est accrue avec l'avènement de WINSock (Windows Socket), qui a conduit à 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 à jour, les correctifs et les exigences de compatibilité sont traités dans la RFC 1122. Kern et Partridge ont publié un article Améliorer les estimations aller-retour dans les 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 les algorithmes d'amélioration des performances.



Vous avez aimé l'article ? Partagez-le