TCP fornisce ai livelli superiori un'interfaccia a stream (ovvero, le applicazioni "sopra" lavorano con un flusso continuo di dati), e lo spezza in pacchetti per passarlo al protocollo IP (suo livello sottostante).

Per come funziona IP, non c'è nessuna garanzia che dall'altra parte i pacchetti arrivino nell'ordine in cui sono stati spediti (e alcuni si potrebbero anche perdere), per cui il protocollo TCP deve essere in grado di gestire queste situazioni senza che ai livelli superiori si rompa l'illusione di star lavorando con un flusso continuo di dati.
Per fare questo da un lato il software TCP del destinatario ha un qualche buffer in cui va ad inserire temporaneamente i pacchetti che gli arrivano, perché, se non è ancora arrivato il pacchetto 4 ma sono arrivati il 5 e il 6, TCP non può passare il 5 e il 6 all'applicazione, ma deve aspettare che arrivi il 4 per poter fornire il flusso di dati nell'ordine in cui è stato scritto dal mittente. Ci sono inoltre tutta una serie di meccanismi di acknowledgment, timeout, checksum & co. per fare in modo che se un pacchetto risulta perso o corrotto il mittente lo spedisce nuovamente per fare in modo che la connessione "virtuale" tra le due applicazioni non risulti corrotta.