Deconstructing the TCP 3-Way Handshake & State Machine
A deep dive into SYN, SYN-ACK, and ACK packets, sequence numbers, and how reliable transport connections are established and terminated.
Why the 3-Way Handshake Exists
In modern networking, the Transmission Control Protocol (TCP) provides reliable, ordered, and error-checked delivery of a stream of octets between applications running on hosts communicating via an IP network.
Unlike UDP (which is connectionless and "fire-and-forget"), TCP guarantees delivery. But before any application data (like an HTTP GET request) can travel, both sides must synchronize their Initial Sequence Numbers (ISNs).
Step-by-Step Breakdown
1. **SYN (Synchronize)**: - The client picks a random Initial Sequence Number (e.g., `Seq = 1000`). - It sends a TCP packet with the **SYN** control flag set to `1` to the server's listening port (e.g., port 443). - The client transitions into the `SYN_SENT` state.
2. **SYN-ACK (Synchronize-Acknowledgment)**: - The server receives the SYN. - It acknowledges the client's sequence number by sending `Ack = 1001` (client's Seq + 1). - The server also picks its own random Initial Sequence Number (e.g., `Seq = 5000`) and sets the **SYN** flag. - The server transitions into the `SYN_RECEIVED` state.
3. **ACK (Acknowledgment)**: - The client receives the server's SYN-ACK. - It acknowledges the server's sequence number by sending `Ack = 5001` (server's Seq + 1). - Both client and server transition into the `ESTABLISHED` state.
Client (192.168.1.100) Server (93.184.216.34)
| |
| ---- SYN (Seq=1000) ---------------------> | (SYN_RECEIVED)
| |
| <--- SYN-ACK (Seq=5000, Ack=1001) --------- |
| |
(ESTABLISHED) |
| ---- ACK (Seq=1001, Ack=5001) -----------> | (ESTABLISHED)
| |
| ==== DATA TRANSFER BEGINS (HTTP GET) ==== |Connection Teardown (4-Way Handshake)
When either endpoint is ready to close the connection, a 4-step teardown process occurs using the **FIN** (Finish) flag: - Endpoint A sends `FIN` $\rightarrow$ Endpoint B sends `ACK`. - Endpoint B sends its own `FIN` $\rightarrow$ Endpoint A sends `ACK`. - The initiator waits in `TIME_WAIT` (typically 2 * Maximum Segment Lifetime) before destroying the socket to ensure late-arriving packets do not disrupt subsequent connections.