Programmation réseau - TCP. Application client-serveur sur un socket de flux TCP Réduire la congestion en réduisant les données envoyées sur le réseau

Voyager à travers 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. Il y a d'abord une poignée de main (Bonjour. | Bonjour. | Discutons ? | Allons-y.), après quoi la connexion est considérée comme établie. Ensuite, les paquets sont échangés via cette connexion (une conversation est en cours) et il est vérifié si le paquet a atteint le destinataire. Si le colis est perdu, ou arrive mais cassé somme de contrôle, puis il est renvoyé (« je répète, je n’ai 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 de cycles d'horloge/mémoire, ce qui n'est pas le moins important 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 avec lequel le serveur envoie des pages à notre navigateur. HTTP est désormais largement utilisé dans World Wide Web pour obtenir des informations sur des sites Web. L'image montre une lampe 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 les voyants :

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

La méthode HTTP est généralement un mot anglais court écrit en majuscules et 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 permet de demander le contenu d'une 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 : fermer Cache-Control : pas de cache, pas de magasin, doit revalider Pragma : pas de cache Expire : 0 Contenu- 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 allait bien (OK).

La demande et la réponse contiennent 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 suivre.

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 définir l'adresse mazko abcd::1 # windows ~$ curl http://

TCP s'intègre naturellement dans un environnement client/serveur (voir Figure 10.1). Application serveur insectes(écouter) les demandes de connexion entrantes. Par exemple, les services WWW, de transfert de fichiers ou d'accès aux terminaux écoutent les demandes provenant des clients. Les communications en TCP sont initiées par des routines appropriées, qui initient une connexion au serveur (voir le 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 envoyer des messages électroniques entre ordinateurs.

10.2 Concepts TCP

Sous quelle forme les applications doivent-elles envoyer des données en TCP ? Sous quelle forme TCP transmet-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 de base de TCP.

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

Conceptuel Le modèle de connexion implique qu'une application transmette un flux de données à une application homologue. Parallèlement, 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 entretenu deux flux données (voir Fig. 10.2).


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

10.2.2 Segments

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

L'application envoie des données à TCP et ce protocole les place dans tampon de sortie(envoyer un tampon). Ensuite, TCP coupe des morceaux de données du tampon et les envoie en ajoutant un en-tête (cela génère segments- segment). En figue. 10.3 montre comment les données de tampon de sortie TCP est mis en paquets en segments. TCP transmet le segment à IP pour livraison sous forme de datagramme distinct. La mise en paquets des données en morceaux de longueur correcte garantit un transfert efficace, donc TCP attendra que la quantité appropriée de données soit disponible 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 sont souvent impossibles à appliquer aux 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 (suivies en appuyant sur la touche Retour).

Le programme client de l'utilisateur a besoin de TCP pour savoir que les données sont envoyées à l'hôte distant et pour effectuer cette opération immédiatement. Dans ce cas, on utilise pousser vers l'extérieur(pousser).

Si vous regardez les opérations dans une session interactive, vous trouverez de nombreux segments avec peu de données, et de plus, des poppings peuvent être trouvés dans presque tous les segments de données. Cependant, le push ne doit pas être utilisé lors des transferts de fichiers (sauf pour le tout dernier segment), et TCP sera en mesure de regrouper les données en segments de la manière la plus efficace.

10.2.4 Données urgentes

Le modèle de transfert de données de l'application implique un flux ordonné d'octets voyageant vers la destination. En nous référant à nouveau à l'exemple de session interactive, supposons que l'utilisateur appuie sur une touche attention(attention) ou casser(interrompre). L'application distante doit être capable d'ignorer les octets interférents et de répondre à la frappe le plus rapidement possible.

Mécanisme données urgentes(données urgentes) marque les informations spéciales dans un segment comme urgent. Ce faisant, 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 dans les plus brefs délais.

10.2.5 Ports d'applications

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

Plusieurs exemples de ports bien connus et de 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 de services déjà connus via UDP. Il faut rappeler que le trafic vers le port 9 du protocole TCP est complètement isolé du trafic vers le port 9 du protocole UDP.


Tableau 10.1 Ports TCP bien connus et leurs applications correspondantes

Port Application Description
9 Jeter Annuler toutes les données entrantes
19 Chargé Générateur de personnages. Échange de flux de personnages
20 Données FTP Port de transfert de données FTP
21 FTP Port pour le dialogue FTP
23 TELNET Port pour l'enregistrement à distance via Telnet
25 SMTP Port du protocole SMTP
110 POP3 Service d'échantillonnage de courrier pour 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 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 pourra être réutilisé par un autre client. Puisqu’il existe 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 d'adresse. Une connexion TCP est complètement identifiée par l'adresse du socket à chaque extrémité de la connexion. En figue. La figure 10.4 montre la 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 de destination. Vous verrez plus tard que les numéros de port source et 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 simultanément. Des adresses de socket de serveur uniques sont attribuées simultanément à tous ses clients (voir Fig. 10.5).


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

Étant donné qu'un 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 transmission 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 garantir un transfert de données fiable. Le schéma de numérotation TCP est quelque peu inhabituel : chaque transmis via la connexion octuor est 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 doit confirmer que les données ont été reçues. Si l'ACK n'arrive pas dans le délai d'attente, les données sont retransmises. Cette méthode est appelée confirmation positive avec relais(accusé de réception positif avec retransmission).

Le destinataire des données TCP vérifie strictement les numéros de séquence entrants pour vérifier que les données sont reçues dans l'ordre et qu'il ne manque aucune pièce. Étant donné que l'ACK peut être perdu ou retardé 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. 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 dans TCP

10.3.2 Champs Port, Séquence 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 des ports source et de destination, le numéro de séquence du premier octet des données incluses 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’à 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 ne peut être négligé. Supposons que TCP ait envoyé les octets 1 à 50 et qu'il n'y ait plus de données à envoyer. Si des données sont reçues d'un homologue, TCP doit accuser réception de leur réception en envoyant un en-tête sans les données qui y sont attachées. Bien entendu, cet en-tête contient la valeur ACK. Dans le champ séquence - la valeur est 51, c'est-à-dire le numéro de l'octet suivant, qui a l'intention envoyer TCP. Lorsque TCP enverra les données suivantes, le nouvel en-tête TCP aura également un champ de séquence de 51.

10.4 Établir une connexion

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

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

Il y a une caractéristique technique. Chaque côté commence à numéroter chaque octet non pas avec un, mais avec numéro de série aléatoire(nous découvrirons plus tard pourquoi cela est fait). La spécification originale conseille que le numéro de séquence initial soit généré sur la base d'un temporisateur externe de 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 car trois messages sont échangés pour établir une connexion : SYN, SYN et ACK.

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

1. Espace tampon pour recevoir des données

2. Quantité maximale de données transportées dans un segment entrant

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

Notez que chaque partie utilise les opérations 1 et 2 pour indiquer les limites dans lesquelles l'autre partie agira. Un ordinateur personnel peut avoir un petit tampon de réception, mais un superordinateur peut avoir un énorme tampon. La structure de la mémoire d'un ordinateur personnel peut limiter les blocs de données entrants à 1 Ko, mais un superordinateur gère des segments plus grands.

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

En figue. La figure 10.8 montre un exemple de script de connexion. Des numéros de séquence initiaux très simples sont présentés afin de ne pas surcharger le dessin. Notez que dans cette figure, le client est capable de 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 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é ouverture active).

3. Le client TCP reçoit le numéro de séquence initial (1000 dans cet exemple) 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 la taille du plus grand segment que le client peut recevoir (1 460 octets).

4. Lorsqu'un SYN arrive, le serveur TCP reçoit le mien numéro de séquence de départ (3000). Il envoie un segment SYN contenant le 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 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 l'ACK 3001 (le premier octet de données envoyé par le serveur doit être numéroté 3001).

6. Le client TCP demande à son application d'ouvrir la 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 sont prêts à échanger des données. La spécification TCP permet également un autre scénario (pas très réussi), dans lequel des applications homologues s'ouvrent activement simultanément.

10.4.2 Définition des valeurs des paramètres IP

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

Par exemple, une application peut sélectionner une 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 type de service, ces valeurs peuvent théoriquement différer selon les différentes directions des 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 implique des options de sécurité gouvernementales ou militaires, chaque point final de la 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 avoir terminé la confirmation en trois étapes de la création de la connexion (voir Figure 10.9). La norme TCP permet aux données normales d'être incluses dans les segments d'accusé de réception, mais elles ne seront transmises à l'application qu'une fois la connexion établie. Pour simplifier la numérotation, des messages de 1 000 octets sont utilisés. Chaque segment d'en-tête TCP possède un champ ACK identifiant le numéro de séquence d'octets qui doit être reçu du partenaire de connexion..


Riz. 10.9.Échange de données simple et flux ACK

Le premier segment envoyé par le client contient les octets 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 1 000 octets de données (commençant par le numéro 3 001). 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 du client devrait être 2001.

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

Le serveur économise la bande passante de connexion en utilisant un seul ACK pour indiquer le succès du transfert de tous les segments.

En figue. 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 qu'à la réception d'un segment perdu, le récepteur envoie un seul ACK confirmant le transfert des deux segments.


Riz. 10.10. Perte et retransmission de données

10.6 Fermeture d'une connexion

La terminaison normale d'une connexion s'effectue à l'aide de la même procédure de triple prise de contact que lors de l'ouverture d'une connexion. Chaque partie peut commencer à fermer la connexion en utilisant le scénario suivant :

UN:

B :"Bien".

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

UN:"Bien".

Supposons le scénario suivant (bien qu'il soit extrêmement rarement utilisé) :

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

DANS:"D'accord. Cependant, il y a des données..."

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

UN:"Bien".

Dans l'exemple ci-dessous, la connexion est fermée par le serveur, comme c'est souvent le cas pour les connexions client/serveur. Dans ce cas, une fois que l'utilisateur est entré dans la session telnet La commande de déconnexion amène le serveur à lancer une demande de fermeture de 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 (Final Segment - FIN), informant son homologue qu'il n'y a plus de données à envoyer.

3. Le TCP du client envoie un ACK dans le segment FIN.

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

5. L'application client demande à son TCP de fermer la connexion.

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. Fermer une connexion

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

10.6.1 Résiliation brutale

Chaque partie peut demander une interruption brutale (fermeture 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 grave qu'il ne peut pas résoudre par ses propres moyens. La terminaison brutale est demandée en envoyant un ou plusieurs messages de réinitialisation au homologue, indiqués par un indicateur spécifique dans l'en-tête TCP.

10.7 Contrôle du débit

Le récepteur TCP est chargé du flux de données entrant et détermine la quantité d'informations qu'il peut accepter. Cette limitation affecte l'expéditeur TCP. L'explication suivante 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 homologue alloue de l'espace pour le tampon d'entrée de la connexion et en informe l'autre partie. Généralement, la taille du tampon est exprimée sous la forme d'un nombre entier de tailles maximales de segment.

Le flux de données entre dans le tampon d'entrée et y est stocké avant d'être transmis à l'application (définie par le port TCP). En figue. La figure 10.12 montre un tampon d'entrée pouvant accepter 4 Ko.


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

L'espace tampon est rempli au fur et à 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 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 qu'un client ait envoyé un fichier à un serveur FTP exécuté sur un ordinateur multi-utilisateurs 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 disque, le programme attend que ces opérations soient terminées. 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é jusqu'à la fin du tampon. En figue. 10.12, tout d'abord la totalité du tampon est disponible et, par conséquent, 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 plus de simplicité, 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 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 être augmenté ou diminué en fournissant un retour d'information à l'expéditeur.

Que se passe-t-il si le segment arrivant peut être placé dans la fenêtre de réception, mais qu'il arrive dans le désordre ? Il est généralement supposé que toutes les implémentations stockent les données entrantes dans une fenêtre de réception et envoient un accusé de réception (ACK) uniquement pour l'ensemble du bloc contigu de plusieurs segments. C'est la bonne méthode, car sinon, la suppression des données qui arrivent dans le désordre réduira 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 : la quantité de données déjà envoyées et reconnues, et la taille actuelle de la fenêtre de réception du destinataire. Actif envoi d'espace(espace d'envoi) s'étend du premier octet non acquitté jusqu'au bord gauche de la fenêtre de réception actuelle. Partie fenêtre, utilisé envoyer, indique la quantité de données supplémentaires qui 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 spécifiés lors de l'établissement de la connexion. Riz. La figure 10.13 illustre certaines des caractéristiques du mécanisme de transfert de données.

1. L'expéditeur commence 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 elle devra peut-être être retransmise.

3. Le message ACK pour le premier Ko arrive et les 2 Ko de données suivants sont envoyés. Le résultat est présenté 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 que la totalité est reçue par le récepteur). ACK restaure la taille de la fenêtre d'envoi à 4 Ko.

Riz. 10.13. Fenêtre d'envoi

Plusieurs fonctionnalités intéressantes méritent d’être soulignées :

■ L'expéditeur n'attend pas un ACK pour chaque segment de données qu'il envoie. La seule restriction concernant le 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 à 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

En figue. La figure 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 ACCK(accusé de réception) contient des informations sur le prochain segment attendu qui devrait 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 maximale de segment

Paramètre "taille maximale des segments"(taille maximale du segment - MSS) est utilisé pour déclarer la plus grande partie de données pouvant être acceptée et traitée par le système. Cependant, le nom est quelque peu inexact. Généralement en TCP segment traité comme en-tête plus 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, MSS reflète le plus grand charge utile au niveau du récepteur lorsque les en-têtes TCP et IP font 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 déclarée MSS + 40 – (somme des longueurs d'en-tête TCP et IP)

Les pairs échangent généralement des valeurs MSS dans les messages SYN initiaux lors de l'ouverture d'une connexion. 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 maximale du segment est codée sous la forme d'une entrée de 2 octets suivie d'une valeur de 2 octets, c'est-à-dire la plus grande valeur sera 2 16 -1 (65 535 octets).

MSS impose une limitation sévère sur les données envoyées en 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 l’itinéraire 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 indicateur SYN de 1 et un indicateur ACK de 0. Le SYN initial est le seul un segment qui a un champ ACK avec une valeur de 0. Notez que les outils de sécurité utilisent cette fonctionnalité pour identifier les demandes d'entrée pour une session TCP.

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

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

Dans une réponse d'octroi à une demande de connexion, les deux indicateurs (SYN et ACK) sont égaux à 1. Le système répondant indique le numéro de séquence de départ dans le champ approprié et la taille de la fenêtre de réception dans le champ Fenêtre. La taille maximale du segment que le destinataire souhaite utiliser se trouve généralement dans la réponse à la demande de connexion (dans le choix). 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 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 initial(basé sur la valeur actuelle de la minuterie interne 32 bits). Comment cela se fait-il ?

Imaginons ce qui se passerait si le système s'effondrait. Supposons que l'utilisateur ait ouvert une connexion juste avant le crash et envoyé 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à démarrées et les numéros de port attribués. L'utilisateur rétablit la connexion. Les numéros de port ne correspondent pas aux attributions 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 partie à la toute fin de la connexion peut ne pas savoir que son partenaire s'est écrasé et a ensuite été restauré. Tout cela entraînera de graves perturbations, en particulier lorsqu'il faudra beaucoup de temps pour que les anciennes données transitent par 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 celle de la plage de numéros de séquence de la nouvelle connexion. Les pirates, lorsqu'ils usurpent 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 initial prévisible dans le message. Une fonction de hachage cryptographique basée sur des clés internes constitue la meilleure méthode pour sélectionner des graines sécurisées.

10.8.5 Utilisations courantes 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 inscrit dans le champ confirmation(Numéro d'accusé de réception) lorsque le bit ACK est défini sur 1. Champ fenêtre(Fenêtre) est destiné à la taille actuelle de la fenêtre de réception. Ce champ contient nombre d'octets du numéro d'accusé de réception pouvant être reçus. A noter que cette valeur permet un contrôle précis du flux de données. En utilisant cette valeur, l'homologue indique l'état réel de la fenêtre de réception pendant la session d'échange.

Si une application spécifie une opération push dans TCP, alors l'indicateur PUSH est mis à 1. Le TCP récepteur DOIT répondre à cet indicateur en délivrant rapidement les données à l'application dès que l'expéditeur veut les transmettre.

Le drapeau URGENT, lorsqu'il est mis à 1, implique un transfert de données urgent, et le pointeur correspondant doit faire référence au dernier octet des données urgentes. Une utilisation typique des données urgentes consiste à envoyer des signaux d'abandon ou d'abandon à partir du terminal.

Les données urgentes sont souvent appelées informations hors bande(hors bande). Cependant, ce terme est imprécis. Les données urgentes sont envoyées dans le flux TCP normal, bien que certaines implémentations puissent disposer de mécanismes spéciaux pour indiquer à l'application que des données urgentes sont arrivées, 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 lorsque la connexion doit se terminer anormalement. Le même indicateur est défini dans la réponse lorsqu'un segment arrive 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 pour le pseudo-en-tête créé à partir de l'en-tête IP. Lors du calcul de la somme de contrôle TCP, le champ correspondant a la valeur 0. Sur la Fig. La figure 10.15 montre un pseudo-en-tête qui ressemble beaucoup à celui utilisé dans une somme de contrôle UDP.


Riz. 10h15. 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 d'un segment arrivant 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 fonctionnement de l'analyseur Renifleur de 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 contient 12 octets de données.


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

Analyseur Renifleur convertit la plupart des valeurs sous forme décimale. Cependant, les valeurs des indicateurs sont affichées au format hexadécimal. Un indicateur avec une valeur de 12 représente 010010. La somme de contrôle est également affichée en hexadécimal.

10.10 Prise en charge des sessions

10.10.1 Sondage de fenêtre

Un émetteur rapide et un récepteur lent peuvent former une fenêtre de réception de taille 0 octet. Ce résultat est appelé fermer la fenêtre(Fermer la fenêtre). Lorsque de l'espace libre devient disponible 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 mémorisable(minuterie persistante) lors de la fermeture de la fenêtre temporaire. La valeur de la minuterie est le délai d'expiration de la retransmission. À la fin du chronomètre, un segment est envoyé au partenaire détection de fenêtre(sonde de fenêtre ; certaines implémentations incluent également des données). Le sondage amène l'homologue à renvoyer un ACK qui signale l'état actuel de la fenêtre.

Si la fenêtre reste toujours à une taille nulle, la valeur du timer en cours de sauvegarde 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 s'ouvre, que l'utilisateur termine le processus ou que l'application expire.

10.11 Terminer une session

10.11.1 Temps mort

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

Lorsque TCP atteint le premier seuil de retransmission, il demande à IP de vérifier le routeur défaillant et informe simultanément l'application qu'il y a un problème. TCP continue de transférer les données jusqu'à ce que le deuxième seuil soit atteint avant de libérer la connexion.

Bien entendu, 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 après cela, TCP continuera à tenter d'accéder à la destination jusqu'à l'expiration du délai d'attente (auquel cas le problème peut être résolu). Ensuite, l'application est informée que le point de destination est inaccessible.

Une application peut définir son propre délai d'expiration pour la livraison des données et effectuer ses propres opérations à la fin de cet intervalle. Habituellement, la connexion est interrompue.

10.11.2 Maintenir une connexion

Lorsqu'une connexion incomplète a des données à transmettre pendant une longue période, elle devient inactive. Pendant une période d'inactivité, le réseau peut tomber en panne ou les lignes de communication physiques peuvent être interrompues. 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 - consomme beaucoup de mémoire informatique. 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 concernant maintenir la connexion(keep-alive), qui teste les connexions inactives. De tels messages sont périodiquement envoyés au partenaire pour vérifier son existence sur le réseau. La réponse doit être des messages ACK. L'utilisation de messages keep-alive est facultative. Si le système dispose de cette capacité, l'application peut la remplacer par ses propres moyens. Période estimée défaut Le délai d'expiration de la maintenance de la connexion est de deux heures complètes !

Rappelons qu'une application peut paramétrer son propre timer, selon lequel elle décidera à son niveau de mettre fin ou non à la connexion.

10.12 Performance

Quelle est l’efficacité du 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 la latence du réseau physique utilisé limitent considérablement le débit. Une mauvaise qualité de transfert des données entraîne la suppression d'un grand volume de datagrammes, ce qui entraîne des retransmissions et réduit par conséquent l'efficacité de la bande passante.

L'extrémité réceptrice doit fournir suffisamment d'espace tampon pour permettre à l'expéditeur d'envoyer 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 lors de la négociation de la taille de la fenêtre). Pour maintenir un flux constant de données depuis la source, l'extrémité réceptrice doit disposer d'une fenêtre d'une taille au moins égale au produit de la bande passante et de la latence.

Par exemple, si la source peut envoyer des données à un débit de 10 000 octets/s et que l'ACK prend 2 secondes pour être renvoyé, l'autre côté doit fournir une fenêtre de réception d'au moins 20 000 octets, sinon le flux de données ne sera pas transmis. être 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. effectuer certaines opérations et passer à d’autres. L'hôte peut prendre en charge de manière interactive plusieurs utilisateurs locaux, des processus en arrière-plan par lots et des dizaines de connexions de communication simultanées. Le changement de contexte vous permet de gérer toutes ces opérations tout en 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 du changement de contexte.

Les ressources CPU de l'ordinateur sont requises pour les opérations de traitement des en-têtes 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 que l'administrateur réseau puisse les configurer en fonction de leurs exigences locales. Par exemple, la possibilité d'ajuster la taille du tampon à la bande passante et à la latence du réseau améliorera considérablement les performances. Malheureusement, de nombreuses implémentations n’accordent pas suffisamment d’attention à ce problème et programment de manière rigide les paramètres de communication.

Supposons que l'environnement réseau soit parfait : les ressources sont suffisantes et le changement de contexte s'effectue plus rapidement que les cowboys ne sortent leur revolver. D’excellentes performances seront-elles obtenues ?

Pas toujours. La qualité du développement des logiciels TCP compte également. Au fil des années, 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 conforme à la RFC 1122, qui définit les exigences relatives à la couche de communication des hôtes Internet.

L’exception est tout aussi importante et l'utilisation 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 transferts inutiles de petites quantités de données et disposent de minuteries intégrées pour libérer les ressources réseau qui ne sont actuellement pas utilisées.

10.13 Algorithmes pour améliorer les performances

Passant à la connaissance de la partie plutôt complexe de TCP, nous examinerons les mécanismes permettant d'augmenter les performances et de résoudre les problèmes avec un débit réduit. Cette section aborde les problèmes suivants :

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

■ Guérir de Syndrome de la « fenêtre désemparée »(syndrome de la fenêtre idiote) empêche les applications mal conçues de surcharger 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 d'expiration de retransmission calculé(calculing retransmission timeout) est basé sur la négociation du temps réel de session, réduisant le nombre de retransmissions inutiles, mais n'entraîne pas de retards importants pour les échanges de données réellement nécessaires.

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

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

10.13.1 Démarrage lent

Si vous allumez tous les appareils électroménagers de la maison en même temps, le réseau électrique sera surchargé. Dans les réseaux informatiques démarrage lent empêche les fusibles secteur de sauter.

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 garantir qu'une 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 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 jusqu'à ce qu'elle reste plus petite que la fenêtre de réception. Si le réseau n’est pas encombré, la fenêtre de chargement atteindra progressivement la taille de la fenêtre de réception. Dans des conditions normales de transfert, les tailles de ces fenêtres seront les mêmes.

Notez qu’un démarrage lent n’est pas si lent que ça. Après le premier ACK, la taille de la fenêtre de chargement est de 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 produise. Le comportement de la fenêtre de chargement dans ce cas est discuté ci-dessous.

10.13.2 Syndrome de la fenêtre désemparée

Lors des premières implémentations TCP/IP, les développeurs ont été confrontés au phénomène Syndrome de la « fenêtre désemparée »(Silly Window Syndrome - SWS), qui apparaît 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 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 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 récepteur envoie un ACK signifiant "Merci. J'ai reçu le 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.

Bien entendu, les situations réelles ne sont pas si extrêmes. Un expéditeur rapide et un récepteur lent échangeront de petites données (par rapport à la taille maximale du segment) et basculeront sur une fenêtre de réception presque pleine. En figue. La figure 10.18 montre les conditions d'apparition du syndrome de la « fenêtre stupide ».


Riz. 10.18. Fenêtre de réception de tampon avec un très petit espace libre

Résoudre ce problème n'est pas difficile. Dès que la fenêtre de réception est réduite à une longueur inférieure à cette taille cible, TCP commence à tromper l'expéditeur. Dans cette situation, TCP ne doit pas indiquer à l'expéditeur supplémentaire espace de fenêtre lorsque l'application réceptrice lit les données du tampon par petits morceaux. Au lieu de cela, vous devez garder les ressources libérées secrètes pour l'expéditeur jusqu'à ce qu'elles soient suffisantes. Une taille de segment unique est recommandée, à moins que l'intégralité du tampon d'entrée stocke un seul segment (dans ce dernier cas, une taille de demi-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 maximale du segment)

TCP commence à mentir 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 à partir de la formule. Notez qu’il n’y a aucun préjudice pour l’expéditeur, puisque l’application réceptrice ne serait de toute façon pas en mesure de traiter une grande partie des données qu’elle attend.

La solution proposée peut être facilement vérifiée dans le cas évoqué ci-dessus avec une sortie 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 c'est souvent le cas en pratique). L'expéditeur rapide remplira le tampon d'entrée, mais le destinataire indiquera qu'il n'a pas d'espace libre pour accueillir les informations et n'ouvrira pas cette ressource tant que sa taille n'atteindra pas la totalité du segment.

10.13.3 Algorithme de Nagle

L'expéditeur doit, indépendamment du 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 qui permet de réduire le nombre de datagrammes courts envoyés sur le réseau.

L'algorithme recommande de retarder le transfert (et le transfert) des données en attendant un ACK des données précédemment transmises. Les données accumulées sont envoyées après avoir reçu un ACK pour une information précédemment envoyée, ou après avoir reçu des données à envoyer dans la quantité 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 le plus rapidement possible.

10.13.4 ACK retardé

Un autre mécanisme permettant d'améliorer les performances est la méthode de délai ACK. La réduction du nombre d’ACK réduit la 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 :

■ Plusieurs segments peuvent être reconnus avec un seul ACK.

■ L'application réceptrice est capable de recevoir une certaine quantité de données dans le délai d'expiration, c'est-à-dire l'ACK peut contenir l'en-tête de sortie et ne nécessite pas de générer un message séparé.

Pour é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é 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 reste encore 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, le renvoi est généralement beaucoup plus lent). Si un segment entier arrive, vous devez y répondre dans la même seconde avec un message ACK.

10.13.5 Expiration du délai de retransmission

Après l'envoi du segment, TCP définit une minuterie et surveille l'arrivée de l'ACK. Si un ACK n'est pas reçu dans le délai d'expiration, TCP retransmet le segment (relais). Cependant, quel devrait être le délai d’attente ?

S'il est trop court, l'expéditeur inondera le réseau en transmettant des segments inutiles qui dupliquent des informations déjà envoyées. Un délai d'attente trop long empêchera la réparation rapide des segments qui sont réellement détruits lors du transfert, ce qui réduira le débit.

Comment choisir le bon délai d’attente ? Valeur adaptée à la haute vitesse réseau local, ne conviendra pas aux connexions à distance avec de nombreux hits. Cela signifie que le principe « une valeur unique 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éliorer les estimations du temps d'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 les nouvelles implémentations. Nous les examinerons brièvement ci-dessous.

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

De bonnes solutions pour les quantités suivantes peuvent être obtenues à partir de statistiques de base (voir Figure 10.19) pour aider à calculer le temps d'attente. Cependant, il ne faut pas se fier aux moyennes, puisque plus de la moitié des estimations seront supérieures à la moyenne statistique. En considérant quelques valeurs aberrantes, nous pouvons obtenir de meilleures estimations qui prennent en compte la distribution normale et réduisent 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. Vous pouvez utiliser des estimations assez grossières 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 correcte du délai d'attente, un autre facteur à prendre en compte est la modification du temps de cycle due aux conditions actuelles du réseau. Ce qui se passe en ligne à la dernière minute est plus important que ce qui s’est passé il y a une heure.

Supposons que nous calculions la moyenne du cycle pour une très longue session. Supposons que le réseau soit légèrement chargé au début et nous avons identifié 1 000 petites valeurs, mais il y a ensuite eu une augmentation du trafic avec une augmentation significative de la latence.

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

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

Une valeur plus raisonnable serait 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 de α est comprise entre 0 et 1. Augmenter un se traduit par une plus grande influence du temps de cycle actuel sur la moyenne lissée. Puisque les ordinateurs peuvent rapidement effectuer une division par puissances de 2 en décalant 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 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 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 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

Se pose maintenant la question du choix d’une valeur pour le timeout de retransmission. L'analyse des valeurs de temps de cycle montre un écart significatif de ces valeurs par rapport à la valeur moyenne actuelle. Il est logique de fixer une limite à l’ampleur des écarts. Une bonne valeur pour le délai d'attente de retransmission (dans les normes RFC, cette valeur est appelée Retransmission TimeOut - RTO) est donnée par la formule suivante avec une contrainte d'écart lissé (SDEV) :

T = délai d'attente de retransmission = SRTT + 2 × SDEV

T = SRTT + 4 × SDEV

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

DEV = | Temps du dernier cycle - ancien SRTT |

La formule de lissage est alors utilisée pour prendre en compte cette dernière valeur :

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

Une question demeure : quelles valeurs initiales prendre ? Recommandé:

Délai d'attente initial = 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 des données.

10.13.6 Exemple de statistiques

Dans quelle mesure le délai d'attente calculé ci-dessus sera-t-il efficace ? Lorsque cette valeur a été implémentée, 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 constitué de purs messages ACK), seuls 0,6 % ont été dupliqués. Il convient de garder à l'esprit 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 renvoi

Les formules présentées ci-dessus utilisent le temps de cycle comme intervalle entre l'envoi d'un segment et la réception d'un accusé de réception. Supposons toutefois qu'aucun accusé de réception ne soit reçu dans le délai imparti 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. Valeur actuelle du temps de cycle lissé et écart lissé conservent leurs valeurs jusqu'à ce que la confirmation soit reçue pour transférer un certain segment sans le renvoyer. A partir de ce moment, les calculs reprennent sur la base des valeurs enregistré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 :

■ Taux de retransmission réduit

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

10.13.9 Freinage exponentiel

Après la retransmission, le délai d'attente est doublé. Mais 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é freinage exponentiel(retard exponentiel).

Si le défaut réseau continue de se produire, le délai d'attente doublera jusqu'à ce que la valeur maximale prédéfinie soit atteinte (généralement 1 minute). Après un délai d'attente, un seul segment peut être envoyé. Un délai d'attente se produit également lorsque la valeur prédéfinie pour le nombre de transferts de données sans réception d'ACK est dépassée.

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

La réduction de la quantité de données envoyées est un peu plus complexe que les mécanismes évoqués ci-dessus. Cela commence à fonctionner, tout comme le démarrage lent déjà mentionné. Mais comme une limite est fixée au niveau de trafic qui peut initialement entraîner des problèmes, la vitesse d'échange ralentira en réalité en raison d'une augmentation de la taille de la fenêtre de chargement pour un segment. Vous devez définir les valeurs limites pour réduire réellement 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 complète 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, à chaque ACK reçu, ajoutez une valeur plus petite à la fenêtre de chargement, qui est sélectionnée en fonction du taux d'augmentation par 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 idéal peut fournir une représentation simplifiée du fonctionnement du mécanisme de récupération. Supposons que la fenêtre de réception du partenaire (et la fenêtre de chargement actuelle) avait une taille de 8 segments avant la détection du délai d'attente et que la limite était 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 de 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 la retransmission après expiration du délai nécessite une confirmation de la réception de toutes les données envoyées, 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 représentés sur la Fig. 10h20. La taille de la fenêtre augmente de façon exponentielle, doublant pendant la période de démarrage lent, et augmente linéairement une fois la limite atteinte.


Riz. 10h20. Limitation de la vitesse de transfert en cas de congestion

10.13.11 ACK en double

Certaines implémentations utilisent une fonctionnalité facultative appelée renvoi rapide(retransmission rapide) - afin d'accélérer le réenvoi des données dans certaines conditions. Son idée de base implique que le destinataire envoie des ACK supplémentaires indiquant une lacune dans les données reçues.

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


Riz. 10.21. ACK en double

L'expéditeur ne retransmet pas immédiatement les données car IP peut normalement transmettre les données au destinataire sans séquence d'envoi. Mais lorsque plusieurs ACK de données en double supplémentaires sont reçus (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 que le réseau est capable de fournir une quantité suffisante de données et n'est donc pas surchargé. Dans le cadre de l'algorithme global, une légère réduction de la taille de la fenêtre de chargement est effectuée lorsqu'il y a une réelle augmentation du trafic réseau. Dans ce cas, le processus de redimensionnement radical lors de la restauration de l'œuvre n'est pas appliqué.

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. Toutefois, ce message n'est ni ciblé ni efficace, car la connexion qui reçoit le message ne génère peut-être pas beaucoup 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 l'équipe netstat, pour voir bon nombre des mécanismes décrits ci-dessus à l’œuvre.

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 avec accusé de réception uniquement (104216 retardés)
Notons un grand nombre

ACK retardé.

Sonder l'ouverture de la fenêtre

taille nulle.

Ce sont les messages SYN et FIN.
762469 accusés de réception (pour 226904227 octets)
Signaler l'arrivée des paquets

Hors de la séquence.

1510769 paquets (314955304 octets)
9006 paquets complètement dupliqués (867042 octets)
Résultat du délai d'attente avec réel

livraison de données.

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

certaines données ont été reconditionnées pour inclure des octets supplémentaires lors de leur renvoi.

13452 paquets dans le désordre (2515087 octets)
530 paquets (8 551 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 la clôture
Ce sont des répétitions ultérieures

Envoi en cours.

108 rejetés pour des sommes de contrôle incorrectes
Somme de contrôle TCP invalide.
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 points)
4100 connexions embryonnaires abandonnées
572187 segments mis à jour RTT (sur 587397 tentatives)
Tentatives de modification ayant échoué

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

26 connexions interrompues suite à l'expiration du délai de réenvoi
Tentatives ultérieures infructueuses

renvoyer, indiquant une connexion perdue.

Délais d'attente de vérification

zéro fenêtre.

Délais d'expiration de la vérification

connexion rompue.

472 connexions interrompues 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 d'expiration du renvoi des données et le contrôle de 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 des performances adéquates à ses propres utilisateurs et sera un mauvais voisin pour les autres systèmes du réseau, l'empêchant de se remettre d'une surcharge temporaire et générant un trafic excessif entraînant la suppression de datagrammes.

10.15 Obstacles à la productivité

TCP a prouvé sa flexibilité en fonctionnant sur des réseaux avec des taux de transfert de centaines ou de millions de bits par seconde. Ce protocole a obtenu de bons résultats dans les réseaux locaux modernes avec les topologies Ethernet, Token-Ring et Fiber Distributed Data Interface (FDDI), ainsi que pour les liaisons de communication à faible débit ou les connexions longue distance (similaires aux liaisons satellite).

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 offrant une bande passante de plusieurs centaines ou milliers de mégaoctets. Pour comprendre les problèmes impliqués, considérons un exemple simple (quoique irréaliste).

Supposons que lors du déplacement d'un fichier entre deux systèmes, vous souhaitiez effectuer un flux d'échange continu aussi efficace que possible. Supposons que :

■ La taille maximale du segment du récepteur est de 1 Ko.

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

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

■ L'application réceptrice consomme les données au fur et à mesure de leur arrivée.

■ Les messages ACK arrivent après 2 s.

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

Après 2 s :

RECEVOIR UN ACCUSÉ DU SEGMENT 1, PEUT ENVOYER LE SEGMENT 5.
RECEVOIR L'ACK DU SEGMENT 2, PEUT ENVOYER LE SEGMENT 6.
RECEVOIR L'ACK DU SEGMENT 3, PEUT ENVOYER LE SEGMENT 7.
RECEVOIR L'ACK DU SEGMENT 4, PEUT ENVOYER LE SEGMENT 8.

Après encore 2 s :

RECEVOIR UN ACCUSÉ DU SEGMENT 5, PEUT ENVOYER LE SEGMENT 9.

Si la fenêtre de réception n'était que de 2 Ko, l'expéditeur serait obligé d'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 poser des problèmes sur 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 millions de bits par seconde, 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, c'est-à-dire . 125 000 octets. Mais le plus grand nombre pouvant être écrit dans le champ d’en-tête d’une fenêtre de réception TCP est 65 536.

Un autre problème survient à 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 n'y aura aucun moyen de distinguer les anciens datagrammes en double qui ont été retardés de plus d'une seconde lors de leur déplacement sur Internet des nouvelles données récentes.

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

10.16 Fonctions TCP

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

■Associer des ports à des connexions

■ Initialiser les connexions à l'aide d'une confirmation en trois étapes

■ Effectuer un démarrage lent pour éviter une surcharge du réseau

■ Segmentation des données lors de la transmission

■ Numérotation des données

■ Traitement des segments dupliqués entrants

■ Calcul des sommes de contrôle

■ Contrôle du flux de données via la fenêtre de réception et la fenêtre d'envoi

■ Mettre fin à la connexion de la manière établie

■ Terminer la connexion

■ Transmission de données urgentes

■ Confirmation positive de la réexpédition

■ Calculer le délai d'attente de retransmission

■ Réduction du trafic de retour en cas de congestion du réseau

■ Signalisation que les segments arrivent dans le désordre

■ 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 échange de messages, puis les données sont envoyées, puis la connexion est fermée par échange de messages spéciaux. Chaque étape de l'opération de connexion correspond à une étape spécifique 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 la transition d'état typique entre un serveur et un client situés aux extrémités opposées d'une connexion. Notre objectif n’est pas de fournir une description exhaustive de tous les états possibles lors de l’envoi de données. Il est donné dans la RFC 793 et ​​le document Exigences de l'hôte.

Lors de l'établissement de la connexion, 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 des clients sont présentés dans le tableau 10.4.


Tableau 10.3 Séquence d'état du serveur

Statut du serveur Événement Description
FERMÉ État factice avant de commencer l’établissement de la connexion.
Ouverture passive par une application serveur.
ÉCOUTER (suivi) Le serveur attend une connexion du client.
Le serveur TCP reçoit le SYN et envoie un SYN/ACK. Le serveur a reçu SYN et envoyé 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 partenaires essayaient simultanément d'établir une connexion entre eux (ce qui est extrêmement rare), chacun passerait par les états CLOSED, SYN-SENT, SYN-RECEIVED et ESTABLISHED.

Les participants finaux de la connexion restent à l'état ESTABLISHED jusqu'à ce que l'un des participants démarre fermeture connexions en envoyant le segment FIN. Lors d'une clôture normale, l'initiateur de la 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 Séquence d'états du côté fermant la connexion

États secondaires de clôture Événement Description
ÉTABLI Une application locale demande la fermeture de la connexion.
TCP envoie FIN/ACK.
FIN-ATTENDRE-1 La partie clôturante attend la réponse du partenaire. Rappelons que de nouvelles données peuvent encore arriver du partenaire.
TCP reçoit un ACK.
FIN-ATTENDRE-2 La partie de clôture a reçu un ACK de la part du homologue, mais n'a pas encore reçu de FIN. La partie de clôture attend FIN lors de l'acceptation des 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 la suppression de données en double ou de FIN en double existant encore sur le réseau. La période d'attente est le double de la durée de vie maximale estimée du segment.
FERMÉ

Tableau 10.6 Séquence des états du partenaire lors de la fermeture d'une connexion

Statut de partenaire Événement Description
ÉTABLI TCP reçoit FIN/ACK.
FERMER-ATTENDRE FIN est arrivé.
TCP envoie un ACK.
TCP s'attend à ce que son application ferme la connexion. À ce stade, l’application peut envoyer une quantité de données assez importante.
L'application locale initie la fermeture de la connexion.
TCP envoie FIN/ACK.
DERNIER-ACK TCP attend l'ACK final.
TCP reçoit un ACK.
FERMÉ Toutes les informations de connexion ont été supprimées.

10.17.1 Analyse des états de connexion TCP

Équipe netstat -un vous 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 du port de connexion est répertorié à la fin de chaque adresse locale et externe. Vous pouvez voir qu'il existe 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 sur les implémentations

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

Même la RFC 1122 (document Exigences de l'hôte - exigences pour les hôtes) laisse suffisamment de liberté pour les variations. Chacune des fonctions implémentées est marquée d'un certain niveau de compatibilité :

■ MAI (Autorisé)

■ NE DOIT PAS

Malheureusement, il arrive parfois que des produits ne respectent pas les exigences MUST. En conséquence, les utilisateurs subissent l’inconvénient d’une performance réduite.

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 connus par des processus privilégiés sur le système, si le système d'exploitation local prend en charge cette méthode. Pour améliorer les performances, les implémentations doivent copier et déplacer le moins possible les données envoyées ou récupérées.

Interface de programmation d'applications standard indéfini(ainsi que la politique de sécurité), afin de disposer d'un espace libre pour expérimenter différents ensembles d'outils logiciels. Cependant, cela peut entraîner l'utilisation d'interfaces de programmation différentes sur chaque plate-forme et ne permettra pas de déplacer les logiciels d'application entre les plates-formes.

En fait, les développeurs basent leurs boîtes à outils sur l'interface de programmation Socket, empruntée à Berkeley. L'importance de l'interface logicielle s'est accrue avec l'avènement de WINSock (Windows Socket), ce 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 à niveau, les révisions et les exigences de compatibilité sont traitées dans la RFC 1122. Kern et Partridge ont publié l'article. Améliorer les estimations aller-retour dans des protocoles de transport fiables Dans le magazine Actes de l'ACM SIGCOMM 1987. L'article de Jacobson Prévention et contrôle des embouteillages apparaît dans Actes de l'atelier ACM SIGCOMM 1988. Jacobson a également publié plusieurs RFC révisant les algorithmes de performances.

Client- application serveur sur une socket de flux TCP

L'exemple suivant utilise TCP pour fournir des flux d'octets bidirectionnels ordonnés et fiables. Créons une application complète qui comprend un client et un serveur. Tout d’abord, nous montrons comment construire un serveur à l’aide de sockets de flux TCP, puis une application client 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 des threads est bloquée jusqu'à ce que le serveur accepte de se connecter avec le client. Cette application montre un serveur simple répondant à 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é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); // Attribuer le socket au point de terminaison local et écouter les sockets entrants, essayez ( 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 attendant une connexion entrante Socket handler = sListener.Accept(); string data = null; // Nous avons attendu que le client essaie de nous connecter 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("Texte reçu : " + data + "\n\n"); // Envoie une réponse au client\ string réponse = "Merci pour la demande en " + data.Length.ToString() + " caractères"; octet msg = Encoding.UTF8.GetBytes (réponse); handler.Send(msg); si (données.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 socket sur un point de terminaison local. Avant d'ouvrir un socket pour écouter les connexions, vous devez lui préparer une adresse de point de terminaison locale. Une adresse de maintenance 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 maintenance, ce qui crée le point de terminaison de maintenance.

La classe Dns fournit des méthodes qui renvoient des informations sur les adresses réseau prises en charge par un 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 la baie.

Créons un IPEndPoint pour le serveur en combinant la première adresse IP de l'ordinateur 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 = nouveau 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. Après avoir configuré un point de terminaison local pour écouter les connexions, nous pouvons créer un socket :

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

Transfert 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 Les sockets TCP et UDP sont différents. Vous pouvez y définir, entre autres, les valeurs suivantes :

Dgramme

Prend en charge les datagrammes. La valeur Dgram nécessite que Udp soit spécifié 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. 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 consister à attribuer le socket à l'aide de 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 serveur. Pour qu'un socket client identifie un socket de flux TCP, le programme serveur doit donner un nom à son socket :

SListener.Bind(ipEndPoint);

La méthode Bind() lie un socket à un point de terminaison local. La méthode Bind() doit être appelée 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 Écouter(). En état d'écoute, le socket écoutera les tentatives de connexion entrantes :

SListener.Écouter(10);

Le paramètre définit arriéré, indiquant le nombre maximum de connexions en attente dans la file d'attente. Dans le code ci-dessus, la valeur du paramètre permet de s'accumuler jusqu'à dix connexions dans la file d'attente.

En état d'écoute, vous devez être prêt à accepter de vous connecter avec le client pour lequel la méthode est utilisée Accepter(). Cette méthode obtient une connexion client et complète l'association des noms de client et de serveur. La méthode Accept() bloque le thread du programme appelant jusqu'à ce qu'une connexion arrive.

La méthode Accept() supprime la première demande de connexion de la file d'attente des demandes en attente et crée un nouveau socket pour la traiter. Bien qu'un nouveau socket soit créé, le socket d'origine continue d'écouter et peut être utilisé avec le multithread pour accepter plusieurs demandes de connexion des clients. Aucune application serveur ne doit fermer un 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("En attente d'une connexion sur le port (0)", ipEndPoint); // Le programme fait une pause en attendant une connexion entrante Socket handler = sListener.Accept();

Une fois que le client et le serveur ont établi une connexion entre eux, les messages peuvent être envoyés et reçus à l'aide des méthodes Envoyer() Et Recevoir() classe Prise.

La méthode Send() écrit les données sortantes sur le socket connecté. La méthode Receiver() lit les données entrantes dans le 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 Receiver(). Le protocole exact entre les deux entités communicantes doit être défini à l'avance afin que les applications client et serveur ne se bloquent pas en 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 Fermer():

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

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- empêche le socket de recevoir des données et Envoyer- arrête d'envoyer des données par le socket.

Le socket est fermé en appelant la méthode Close(), qui définit également la propriété Connected du socket sur false.

Client TCP

Les fonctions utilisées pour créer une application client sont plus ou moins similaires à 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.

Les serveurs qui implémentent ces protocoles dans réseau d'entreprise, fournissez 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 de configuration automatique appelé AutoIP, qui est un projet du comité IETF. configuration automatique. Ce protocole est utilisé dans les petits réseaux pour attribuer des adresses IP lien-local aux hôtes. Le protocole AutoIP détermine indépendamment l'adresse IP locale du lien, en utilisant un schéma de négociation avec d'autres hôtes et sans contacter un serveur central.

Utilisation du protocole PPPoE

L'abréviation PPPoE signifie Point-to-Point Protocol over Ethernet. Ce protocole encapsule les données pour la transmission sur un réseau Ethernet avec une topologie pontée.

PPPoE est une spécification de connexion utilisateur Réseaux Ethernetà Internet via une connexion haut débit, telle qu'une ligne d'abonné numérique, un appareil sans fil ou un modem câble. L'utilisation du protocole PPPoE et d'un modem haut débit offre aux utilisateurs un accès local réseau informatique accès individuel authentifié aux réseaux de données à haut débit.

Le protocole PPPoE combine la technologie Ethernet avec le protocole PPP, créant ainsi 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 déterminés pour les utilisateurs et non pour les hôtes. L'avantage de cette approche est que ni la compagnie de téléphone ni le fournisseur de services Internet ne doivent fournir une assistance particulière à cet effet.

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 entre plusieurs utilisateurs, une méthode de comptabilité est nécessaire pour enregistrer les expéditeurs et les destinations du trafic et facturer les utilisateurs. Le protocole PPPoE permet à l'utilisateur et à l'hôte distant qui participent à une session de communication d'apprendre mutuellement leurs adresses réseau lors d'un échange initial appelé détection(Découverte). Une fois qu'une session a été établie entre un utilisateur individuel et un hôte distant (par exemple, un fournisseur de services Internet), la session peut être surveillée à des fins d'accumulation. De nombreuses maisons, hôtels et entreprises fournissent un accès public à Internet via des lignes d'abonné numériques utilisant la technologie Ethernet et le protocole PPPoE.

Une connexion via le protocole PPPoE se compose d'un client et d'un serveur. Le client et le serveur fonctionnent à l'aide de n'importe quelle interface proche des spécifications Ethernet. Cette interface est utilisée pour émettre des adresses IP aux clients et associer ces adresses IP aux utilisateurs et éventuellement aux postes de travail, plutôt qu'à l'authentification basée sur les postes de travail uniquement. Le serveur PPPoE crée une connexion point à point pour chaque client.

Configurer 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-*Avecconducteur approprié. Exemple: