Networking & Sockets

the three-way handshake and teardown

Before two people can have a phone conversation, there is a little ritual: one says 'hello?', the other replies 'hello, I hear you', and the first confirms 'great, I hear you too'. Only after that do they start talking. TCP does the same dance, called the three-way handshake, to set up a connection so both sides agree they can hear each other before any real data flows.

The three steps use small control packets with flags. The client sends a packet with the SYN flag ('I want to start, here is my opening sequence number'). The server replies with SYN-ACK ('I acknowledge yours, and here is mine'). The client replies with ACK ('I acknowledge yours'). Three messages, hence three-way. Now both sides have confirmed they can send and receive, and have agreed on starting sequence numbers so they can detect loss and ordering. This is exactly what connect() triggers on the client and what accept() hands you after it completes on the server. Tearing down is a similar polite exchange: each side sends a FIN ('I am done sending') and the other ACKs it, so both directions close cleanly, often shown as a four-step close.

Why it matters: this is why TCP is called connection-oriented - there really is a setup conversation, costing one round trip, before your data moves, which is part of why TCP has more latency than fire-and-forget UDP. You almost never code the handshake yourself; the kernel does it inside connect() and accept(). But knowing it exists explains why connect() can take time, why a refused connection fails fast (the server answers with a reset instead of SYN-ACK), and why closing a socket is more than just forgetting about it.

Client -> Server: SYN. Server -> Client: SYN-ACK. Client -> Server: ACK. After these three messages the connection is established and bytes may flow. To close: each side sends FIN and gets back an ACK.

Three small packets agree the connection exists before any data is sent.

The handshake is done by the kernel, not your code - you only see its effect as connect()/accept() succeeding or failing. It costs a network round trip, which is a real part of connection latency.

Also called
TCP handshakeSYN/SYN-ACK/ACKconnection setup and teardown三次握手