Fare in modo che il ricevitore rispedisca un ack è il modo migliore, anche se "sembra imbarazzante". Ricorda che l'IP potrebbe suddividere i tuoi dati in più pacchetti e riassemblarli, e questo potrebbe essere fatto più volte durante una trasmissione se vari router sulla strada hanno MTU diversi, e quindi il tuo concetto di "pacchetto" e TCP potrebbe non essere d'accordo.
Molto meglio inviare il tuo "pacchetto", che si tratti di una stringa, un oggetto serializzato o dati binari, e fare in modo che il destinatario esegua tutti i controlli necessari per assicurarsi che sia presente, quindi restituire un riconoscimento.
Il TCP di invio sa quando i dati vengono riconosciuti dall'altra parte, ma l'unico motivo per cui lo fa è per sapere quando può scartare i dati (perché qualcun altro è ora responsabile di portarli all'applicazione dall'altra parte ).
In genere non fornisce queste informazioni all'applicazione di invio, perché (nonostante le apparenze) in realtà non significherebbe molto alla domanda di invio. Il riconoscimento non significa che l'applicazione ricevente ha i dati e ha fatto qualcosa di sensato con essi - significa solo che il TCP mittente non deve più preoccuparsene. I dati potrebbero essere ancora in transito, ad esempio all'interno di un server proxy intermedio o all'interno dello stack TCP ricevente.
"Dati ricevuti con successo" è in realtà un concetto a livello di applicazione:il significato varia a seconda dell'applicazione (ad esempio, per molte applicazioni avrebbe senso considerare i dati "ricevuti" solo dopo che sono stati sincronizzati con il disco sull'unità di ricezione lato). Ciò significa che devi implementarlo tu stesso, perché come sviluppatore dell'applicazione, sei davvero l'unico nella posizione di sapere come farlo in modo sensato per la tua applicazione.