Une idée fausse courante est que le TCP garantit la livraison des données. En réalité, le protocole TCP garantit qu'il va livrer les données à la pile TCP de l'hôte récepteur ou signaler une erreur à l'application émettrice. Malheureusement, le rapport d'erreur n'indique pas la quantité de données effectivement livrées. Il existe également une différence significative entre la pile TCP de l'hôte récepteur et l'application réceptrice.
Il existe deux scénarios d'échec de base. Dans le premier, la pile TCP émettrice ne reçoit pas d'acquittement TCP pour les données qu'elle transmet. Dans ce scénario, l'application d'envoi peut continuer à appeler l'envoi pour mettre plus de données dans le tampon d'envoi de la pile TCP. Une fois que la pile TCP a dépassé la durée de la transmission, le prochain envoi (ou réception) appelé par l'application émettrice indiquera l'erreur ETIMEDOUT. L'application sait maintenant qu'il y a eu un problème mais n'a aucune idée de la quantité de données qui a été transmise avec succès. Le succès signifie que la pile TCP émettrice a reçu un accusé de réception pour les données de la pile TCP réceptrice.
Dans le second scénario, la pile TCP émettrice transmet des données et reçoit une réinitialisation au lieu d'un accusé de réception. La réinitialisation peut indiquer que la pile TCP réceptrice a fermé la socket ou qu'un périphérique réseau, par exemple un pare-feu, a dépassé le temps imparti. La prochaine fois que l'application émettrice appelle pour envoyer (ou recevoir) l'erreur ECONNRESET est indiquée. Vous pourriez penser que dans ce scénario, l'application émettrice pourrait en déduire que seules les données du dernier appel d'envoi ont échoué, mais vous auriez tort. Il est possible que la pile TCP d'envoi ait mis en mémoire tampon les données de plusieurs appels d'envoi en un seul segment TCP et que ce segment ait déclenché la réinitialisation ou qu'une série de segments TCP ait été envoyée avant que la réinitialisation, déclenchée par le premier segment de la série, ne revienne à l'expéditeur. Tout ce que l'application d'envoi peut déduire, c'est que toutes les données n'ont pas été transmises avec succès.
Il existe un troisième scénario de défaillance qui n'a rien à voir avec la pile TCP (envoi ou réception) ou le réseau. Supposons que l'application réceptrice ait un bogue qui l'empêche de lire les données. La pile TCP réceptrice continuera à recevoir les données et à envoyer des accusés de réception TCP jusqu'à ce que le tampon de réception TCP se remplisse. Cela peut cependant représenter jusqu'à 64K octets de données (ou plus si la mise à l'échelle des fenêtres TCP est prise en charge). Si l'application de réception doit être redémarrée, toutes les données du tampon de réception TCP seront perdues. La pile TCP de réception doit (mais ne peut pas) envoyer une réinitialisation à la pile TCP d'envoi lorsque l'application de réception est terminée. Elle enverra une réinitialisation la prochaine fois qu'elle recevra un segment pour la connexion maintenant fermée. Du point de vue de l'application émettrice, ce scénario est similaire au second. Toutefois, il souligne que même si la pile TCP réceptrice accuse réception des données, en cas d'erreur, l'expéditeur ne peut pas supposer sans risque que l'application réceptrice a lu les données.
L'idée à retenir de ces scénarios d'échec est que sans accusé de réception de la couche application, une erreur de temporisation ou de réinitialisation de la transmission indique que certaines, voire toutes les données transmises n'ont peut-être pas été lues par l'application réceptrice. C'est pourquoi je recommande que toutes les applications incluent des accusés de réception de la couche application, soient prêtes à rétablir une connexion et à retransmettre les données non accusées et soient capables de traiter les données en double puisque ce qui a pu être perdu est l'accusé de réception.