TCP State Machine
Watch packets fly and states change — the handshake, teardown, and the weird edge cases.
TCP State Transitions
Why three messages?
The 3-way handshake (SYN, SYN+ACK, ACK) is the minimum needed for both sides to confirm they can send and receive. The client's SYN proves the client can send. The server's SYN+ACK proves the server can both receive and send. The client's final ACK proves the client can receive. Two messages wouldn't be enough — the server would never know its packets are getting through.
Why so many closing states?
TCP close is asymmetric — either side can initiate, and the other side might still have data to send. When you call close(), you're saying "I'm done sending" but you still need to receive whatever the other side hasn't finished sending. That's why there's CLOSE_WAIT (waiting for the app to finish) and FIN_WAIT (waiting for the other side's FIN). The protocol needs separate states to track who has said "I'm done" and who hasn't.
What is TIME_WAIT?
After sending the final ACK, the closing side enters TIME_WAIT for 2x the maximum segment lifetime (typically 60 seconds). This handles two problems: if the final ACK was lost, the other side will retransmit its FIN and we need to be around to re-ACK it. And it prevents old delayed packets from a previous connection being mistaken for packets in a new connection on the same port.
Simultaneous open and close
These are rare but legal. If both sides send SYN at the same time, they both transition through SYN_RECEIVED and end up ESTABLISHED — no server needed. If both send FIN at the same time, they both go through CLOSING instead of the normal FIN_WAIT/CLOSE_WAIT dance. The protocol handles these correctly, even though most TCP implementations rarely see them in practice.