Un errore comune è che il TCP garantisce la consegna dei dati. Ciò che il TCP garantisce in realtà è che consegnerà i dati allo stack TCP dell'host ricevente o che segnalerà un errore all'applicazione di invio. Sfortunatamente, il rapporto di errore non indica quanti dati sono stati effettivamente consegnati. C'è anche una differenza significativa tra lo stack TCP ricevente e l'applicazione ricevente.
Ci sono due scenari di guasto di base. Nel primo, lo stack TCP di invio non riceve le conferme TCP per i dati che sta trasmettendo. In questo scenario, l'applicazione di invio può continuare a chiamare l'invio per mettere più dati nel buffer di invio dello stack TCP. Una volta che lo stack TCP ha terminato la trasmissione, il successivo invio (o ricezione) chiamato dall'applicazione di invio indicherà l'errore ETIMEDOUT. L'applicazione ora sa che c'è stato un problema ma non ha idea di quanti dati sono stati trasmessi con successo. Successo significa che lo stack TCP di invio ha ricevuto una conferma di ricezione dei dati dallo stack TCP di ricezione.
Nel secondo scenario, lo stack TCP di invio trasmette i dati e riceve un reset al posto di un riconoscimento. Il reset può indicare che lo stack TCP ricevente ha chiuso il socket o che qualche dispositivo di rete, forse un firewall, è scaduto. La prossima volta che le chiamate dell'applicazione di invio inviano (o ricevono) l'errore ECONNNRESET viene indicato. Si potrebbe pensare che in questo scenario l'applicazione che invia l'applicazione potrebbe dedurre che sono stati solo i dati dell'ultima chiamata inviata a fallire, ma ci si sbaglierebbe. È possibile che lo stack TCP di invio abbia bufferizzato i dati di più chiamate di invio in un unico segmento TCP e che quel segmento abbia innescato il reset o che una serie di segmenti TCP sia stata inviata prima che il reset, innescato dal primo segmento della serie, sia arrivato di nuovo al mittente. Tutto ciò che l'applicazione di invio può dedurre è che non tutti i dati sono stati trasmessi con successo.
C'è un terzo scenario di guasto che non ha nulla a che fare con lo stack TCP (invio o ricezione) o con la rete. Si supponga che l'applicazione ricevente abbia un bug che le impedisce di leggere i dati. Lo stack TCP ricevente continuerà a ricevere i dati e ad inviare conferme TCP fino al punto in cui il buffer di ricezione TCP si riempie. Questo però può essere fino a 64K byte di dati (o più se è supportato il TCP window scaling). Se l'applicazione ricevente deve essere riavviata, tutti i dati nel buffer di ricezione TCP saranno persi. Lo stack TCP di ricezione dovrebbe (ma non può) inviare un reset allo stack TCP di invio quando l'applicazione di ricezione è terminata. Invierà un reset la prossima volta che riceverà un segmento per la connessione ora chiusa. Dal punto di vista dell'applicazione di invio questo è simile al secondo scenario. Tuttavia, fa notare che anche se lo stack TCP di ricezione riconosce i dati, in caso di errore, non è sicuro per il mittente presumere che l'applicazione ricevente abbia letto i dati.
L'idea di togliere da questi scenari di guasto è che senza un riconoscimento del livello di applicazione, un timeout di trasmissione o un errore di reset indica che alcuni, forse tutti i dati trasmessi potrebbero non essere stati letti dall'applicazione ricevente. Per questo motivo raccomando che tutte le applicazioni includano il riconoscimento del livello di applicazione, siano pronte a ristabilire la connessione e a ritrasmettere i dati non riconosciuti e siano in grado di gestire i dati duplicati, poiché ciò che può essere andato perso è il riconoscimento.