Avant le VOS 17.1, le STCP n'acceptait pas une demande de connexion TCP à moins que l'application serveur n'ait appelé la fonction d'acceptation. Les demandes de connexion étaient placées dans une file d'attente, mais aucune réponse n'était envoyée avant qu'un appel d'acceptation ne supprime la demande de la file d'attente. Une fois que la file d'attente était remplie, le STCP envoyait une réinitialisation en réponse à une demande de connexion.
Depuis la version 17.1, la dynamique des connexions TCP a changé. Désormais, lorsqu'une demande de connexion arrive, en supposant que la file d'attente n'a pas été remplie, la pile STCP envoie immédiatement une réponse acceptant la connexion. La connexion est alors placée dans la file d'attente. Une fois que la file d'attente est remplie, les demandes de connexion suivantes ne reçoivent pas de réponse. Lorsque les appels d'application du serveur acceptent la connexion, la connexion en tête de la file d'attente est supprimée. Ce comportement est maintenant similaire à celui des piles TCP sur la plupart des autres systèmes d'exploitation.
Dans des circonstances normales, ce changement de dynamique n'entraînera aucun changement notable dans le comportement des applications serveur ou client. Toutefois, si l'application serveur ralentit ou si les connexions arrivent plus rapidement que prévu, les connexions peuvent rester dans la file d'attente du journal pendant une période prolongée. Dans ces circonstances, certains comportements intéressants peuvent être constatés.
Le tableau suivant donne un résumé de ce qui se passe lorsqu'une demande de connexion est placée dans la file d'attente en fonction des actions du client. Le client peut ne rien faire, attendre que l'application serveur envoie des données, peut envoyer des données et/ou peut fermer la connexion avec un drapeau FIN (final) (fermeture normale) ou RST (réinitialisation) (fermeture anormale). Les 4 premières colonnes se comportent comme vous l'attendez. Les appels de l'application serveur acceptent de recevoir un socket de la file d'attente, puis appellent recv et soit se bloquent s'il n'y a pas de données, soit reçoivent des données et/ou une indication de fin de fichier en fonction de ce qui se trouve dans le socket. Ce sont les 4 dernières colonnes qui doivent être examinées de plus près.
Rien dans la prise | Données dans la prise | FIN dans la prise | Données dans la prise/
FIN dans la prise |
Données dans la prise/
FIN dans la prise/ Prise client disparue |
FIN dans la prise/
Prise client disparue |
Données dans la prise/
Réinitialisation envoyée |
Réinitialiser l'envoi | ||
Accepter | Prise de retour | Prise de retour | Prise de retour | Prise de retour | Prise de retour | Prise de retour | Accroché | Accroché | |
Première recv | Accroché | Renvoi des données | Retours EOF | Renvoi des données | Retourne l'erreur de réinitialisation | Retours EOF | |||
Deuxième Recv | Accroché | Retours EOF |
Données dans la socket / FIN dans la socket / Client socket disparu
Dans ce scénario, le client a envoyé des données et a coupé la connexion. La version 17.1 du STCP accusera réception de toutes les données envoyées mais n'accusera pas réception du FIN tant que les données dans la file d'attente de réception n'auront pas été remises à l'application. En conséquence, le NIP du client sera retransmis jusqu'à l'expiration du délai de retransmission du client. Une application client bien écrite attendra que l'application serveur ferme son côté de la connexion de sorte que lorsque le FIN expire, le client sera informé d'une erreur. Cependant, si l'application client se contente de fermer la prise sans attendre une indication du serveur, elle ne saura pas que les données qu'elle a envoyées ont pu être perdues.
Lorsque les appels de l'application serveur acceptent un double paquet d'accusé de réception, l'accusé de réception des données mais pas le FIN est envoyé. Comme le client a démonté sa prise, il répond par une réinitialisation. La réinitialisation efface la socket du côté serveur. L'application serveur obtient une erreur de réinitialisation lors du premier ou du deuxième appel à la reconnaissance, selon le temps écoulé entre l'appel à accepter et l'appel à la première reconnaissance. Si ce délai est plus court que le temps nécessaire pour obtenir et traiter le paquet de réinitialisation du client, l'application serveur verra les données. Dans les deux cas, l'application serveur saura qu'une connexion a été établie et qu'elle a été interrompue.
FIN dans la prise / Prise client disparue
Ce scénario diffère du précédent en ce sens qu'il n'y a pas de données dans la prise. Lorsqu'il n'y a pas de données, le FIN est acquitté. L'acceptation renvoie la socket et la reconnaissance renvoie un EOF indiquant qu'elle a reçu le FIN. Toute tentative d'écriture sur la socket, y compris sa fermeture, entraîne le retour d'une réinitialisation parce que le client n'a plus la socket correspondante.
Données dans la prise / Réinitialisation envoyée
Ici, le client envoie des données puis une réinitialisation. Il peut y avoir de nombreuses raisons pour la réinitialisation ; l'une des plus courantes est l'application qui ferme le socket et la pile TCP qui envoie une réinitialisation soit immédiatement, soit après avoir échoué à obtenir un accusé de réception pour le paquet FIN. Ce scénario est similaire au premier, mais la pile TCP du client envoie une réinitialisation avant de détruire sa socket au lieu de simplement détruire la socket. Là encore, une application client bien écrite verra cela comme une erreur ; une application moins bien écrite ne verra pas d'erreur.
La prise du serveur est démolie et toutes les données sont supprimées à la réception de la réinitialisation, de sorte que l'application du serveur ne voit même pas l'indication qu'une connexion a été établie ; elle reste simplement suspendue en attendant une autre connexion.
Réinitialisation envoyée
Là encore, la réinitialisation supprime effectivement la socket de la file d'attente de l'arriéré, de sorte que l'acceptation ne la voit pas et attend une autre demande de connexion.
Alors, que signifie vraiment tout cela ? Premièrement, les applications clientes peuvent maintenant obtenir une réponse de connexion plus rapide mais peuvent devoir attendre plus longtemps pour tout type de bannière ou de message au niveau de l'application. Tout délai d'attente pour cette bannière/message peut devoir être ajusté à la hausse. Deuxièmement, les applications serveur doivent être prêtes à traiter une erreur de l'appel de récupération immédiatement après avoir accepté l'appel. Cela a toujours été une possibilité, mais la probabilité est maintenant plus grande. Enfin, les applications clientes qui envoient des données au serveur et n'attendent aucun message en retour doivent être écrites pour confirmer que l'application serveur a correctement coupé la connexion, sous peine de perdre des données sans le savoir. Là encore, cette possibilité a toujours existé et n'est pas propre au STCP, mais la probabilité est maintenant légèrement plus grande.