Learn how TCP ensures reliable data transmission over the internet. Understand the 3-way handshake, sequence numbers, acknowledgments, retransmission, and connection termination with clear diagrams.

Ever wondered how your messages reach WhatsApp servers correctly, or how Netflix streams video without missing frames? The answer lies in TCP – the backbone of reliable internet communication.
In this guide, I'll break down TCP from the ground up, explaining exactly how computers establish connections, transfer data reliably, and gracefully close connections.
Imagine sending a letter through the postal system. You put it in a mailbox and... hope it arrives. No confirmation, no tracking, no guarantee of delivery order.
Without protocols like TCP, data packets could:
TCP (Transmission Control Protocol) solves all these problems. It's like sending registered mail with:
TCP is a connection-oriented protocol that provides reliable, ordered, and error-checked delivery of data between applications.
| Feature | TCP | UDP |
|---|---|---|
| Connection | Required (handshake) | Not required |
| Reliability | Guaranteed delivery | Best effort |
| Order | Packets arrive in order | No ordering |
| Speed | Slower (more overhead) | Faster |
| Use Cases | Web, Email, File Transfer | Gaming, Video Calls, DNS |
Think of TCP like a phone call – you establish a connection, have a conversation, and hang up. UDP is like shouting across a room – fast, but no guarantee they heard you correctly.
Before any data is exchanged, TCP establishes a connection using a 3-way handshake. This ensures both parties are ready to communicate.
TCP 3-Way Handshake showing SYN, SYN-ACK, and ACK between Client and Server
The client initiates the connection by sending a SYN packet:
Client → Server
"Hey, I want to talk! My sequence number starts at 100."
SYN, SEQ=100
The server responds with its own SYN and acknowledges the client's request:
Server → Client
"Got it! I'm ready too. My sequence number starts at 300.
I'm expecting your next byte to be 101."
SYN-ACK, SEQ=300, ACK=101
The client confirms receipt and the connection is established:
Client → Server
"Perfect! I got your message. Expecting byte 301 from you."
ACK, SEQ=101, ACK=301
Think of it like a phone call:
Now you can start talking!
Without all three, we can't be sure both directions work!
Step through the handshake packet by packet:
Sequence numbers are the backbone of TCP's reliability. Each byte of data gets a unique number.
// Simplified example
const data = "Hello"; // 5 bytes
// TCP breaks this into segments
Segment 1: "Hel" → SEQ=100 (bytes 100-102)
Segment 2: "lo" → SEQ=103 (bytes 103-104)
The receiver uses sequence numbers to:
Once the handshake is complete, data flows between client and server with acknowledgments confirming receipt.
TCP data transfer showing sequence numbers and acknowledgments
1. Client sends: SEQ=100, Data="Hello" (5 bytes)
2. Server receives and replies: ACK=105 (expecting byte 105 next)
3. Client sends: SEQ=105, Data="World" (5 bytes)
4. Server replies: ACK=110
The ACK number tells the sender: "I've received everything up to this byte. Send me the next one."
ACK = Last received SEQ + Data length
If received SEQ=100 with 5 bytes:
ACK = 100 + 5 = 105
TCP uses cumulative acknowledgments. ACK=105 means "I have all bytes up to 104." If the sender gets ACK=105, it knows bytes 100-104 were received successfully.
TCP guarantees every byte arrives correctly through several mechanisms:
Every packet must be acknowledged. No ACK = sender assumes it's lost.
If no ACK arrives within a timeout period, the sender retransmits the packet.
TCP packet loss and retransmission showing timeout and resend
1. Sender sends Packet 1 → ACK received ✓
2. Sender sends Packet 2 → LOST ✗
3. Sender sends Packet 3 → Server can't process (gap)
4. Timeout expires...
5. Sender retransmits Packet 2 → ACK received ✓
6. Server now processes Packets 2 and 3
TCP dynamically calculates timeout based on network conditions. High latency networks get longer timeouts to avoid premature retransmissions.
Every TCP segment includes a checksum – a mathematical fingerprint of the data. If the calculated checksum doesn't match, the packet is discarded.
Data: "Hello"
Checksum: 0x4F2A (calculated from data)
Receiver calculates checksum on received data.
If it matches 0x4F2A → Data is intact ✓
If it differs → Data is corrupted, discard ✗
TCP prevents the sender from overwhelming the receiver using a sliding window.
Receiver: "My buffer has room for 10,000 bytes"
Sender: "OK, I'll only send up to 10,000 bytes before waiting"
[Window Size = 10,000]
TCP also monitors the network itself, slowing down if it detects congestion.
| Algorithm | Purpose |
|---|---|
| Slow Start | Start with small window, increase exponentially |
| Congestion Avoidance | Increase linearly after threshold |
| Fast Retransmit | Retransmit on 3 duplicate ACKs |
| Fast Recovery | Stay in congestion avoidance mode |
Packets may arrive out of order due to different network paths:
Sent: [1] [2] [3] [4] [5]
Arrives: [1] [3] [5] [2] [4]
TCP uses sequence numbers to reorder them:
Buffer after reordering: [1] [2] [3] [4] [5] ✓
Multiple layers of verification:
Just as connections are established with a handshake, they're closed gracefully with a 4-way handshake (sometimes called FIN handshake).
TCP connection termination 4-way handshake with FIN and ACK
Client → Server
"I'm done sending data."
FIN, SEQ=400
Client enters FIN_WAIT_1 state.
Server → Client
"Got it, I acknowledge your finish request."
ACK=401
Client moves to FIN_WAIT_2. Server is in CLOSE_WAIT.
Server → Client
"I'm also done. Closing my side."
FIN, SEQ=500
Server enters LAST_ACK state.
Client → Server
"Acknowledged. Connection fully closed."
ACK=501
Client enters TIME_WAIT (waits 2×MSL), then CLOSED.
Server moves to CLOSED after receiving ACK.
The client waits in TIME_WAIT for about 2 minutes to ensure:
This prevents old packets from a closed connection being confused with a new one.
| Phase | Actions |
|---|---|
| Establish | 3-way handshake (SYN → SYN-ACK → ACK) |
| Transfer | Data segments with SEQ/ACK |
| Close | 4-way handshake (FIN → ACK → FIN → ACK) |
CLOSED
│
│ SYN
▼
SYN_SENT ────SYN-ACK────► ESTABLISHED
│
│ (data transfer)
│
FIN │
▼
FIN_WAIT_1
│ ACK
▼
FIN_WAIT_2
│ FIN
▼
TIME_WAIT
│ (wait 2×MSL)
▼
CLOSED
Let's trace TCP when you visit https://example.com:
1. DNS resolves example.com → 93.184.216.34
2. TCP 3-Way Handshake:
Browser → Server: SYN
Server → Browser: SYN-ACK
Browser → Server: ACK
3. TLS Handshake (for HTTPS)
4. HTTP Request/Response over TCP:
Browser → Server: GET /index.html (SEQ=1000)
Server → Browser: ACK=1050, 200 OK, HTML data
Browser → Server: ACK=5000
5. Connection Close:
Browser → Server: FIN
Server → Browser: ACK
Server → Browser: FIN
Browser → Server: ACK
| Term | Meaning |
|---|---|
| SYN | Synchronize – initiates connection |
| ACK | Acknowledge – confirms receipt |
| FIN | Finish – closes connection |
| SEQ | Sequence number – byte position |
| MSL | Maximum Segment Lifetime |
TCP is the unsung hero of the internet. Every time you:
TCP is working behind the scenes, ensuring your data arrives completely, correctly, and in order.
Understanding TCP makes you a better developer because you can:
The next time you hit Send on a message, remember the elegant dance of SYNs, ACKs, and FINs making it all possible.
Happy networking! 🌐
Have questions about TCP or networking? Drop a comment or reach out on Twitter @srtenginamath!

Written by Sharanayya R Tenginamath
Software Engineer at McD BERL with 4+ years building scalable full-stack applications with React.js, Next.js, TypeScript, FastAPI and Python. Available to join from Oct 12, 2026.

Understand how the internet's phonebook works. A simple guide to A, AAAA, CNAME, MX, and TXT records.
5 min read

Understand the key differences between TCP and UDP protocols. Learn when to use each, how HTTP works on top of TCP, and clear up the common confusion between transport and application layer protocols.
11 min read

Learn the basics of cURL, why developers love it, and how to make your first API requests from the command line.
6 min read