Back to all articles
TCPThree-Way HandshakeTransport LayerNetworking Fundamentals

The TCP Three-Way Handshake: How Two Computers Say Hello

Alex MorganApril 28, 2024

Every conversation starts with a greeting. You walk into a store, you nod at the person behind the counter. You call a friend on the phone, they say hello, you say hello back. You sit down for a job interview, there's a handshake. These rituals of acknowledgment might seem trivial, but they serve a real purpose: they establish that both parties are present, paying attention, and ready to communicate.

Computers do the same thing. When your browser wants to connect to a web server to load a page, it doesn't just start blasting data at the server. It first goes through a careful, three-step introduction ritual called the TCP three-way handshake. It's one of the most elegant little pieces of protocol design in all of networking, and understanding it gives you genuine insight into how the reliable internet works.

Why TCP Needs a Handshake

First, let's remember what TCP actually is. TCP stands for Transmission Control Protocol, and it's one of the two dominant transport-layer protocols on the internet (the other being UDP). TCP's whole value proposition is reliability. It guarantees that data sent from one machine will arrive at the other machine:

  • In the correct order
  • With no missing pieces
  • Without corruption
  • To achieve this, TCP is a connection-oriented protocol. That means before any actual data is exchanged, the two sides have to establish a connection. They have to agree to talk. They have to synchronize some internal bookkeeping. And they do all of this with the three-way handshake.

    The Problem TCP Is Solving

    Imagine you're trying to mail a package to someone you've never contacted before. You don't know if they're home. You don't know if the address is correct. You don't know if they can receive packages. Before you ship an expensive item, you might want to confirm they're ready to receive it.

    TCP has the same problem, plus a few extras specific to networking:

    1. Both sides need to confirm that the other is reachable and ready to receive data.

    2. Both sides need to establish sequence numbers — a way to number their data so that if packets arrive out of order (which happens frequently in real networks), the receiver can reassemble them correctly.

    3. Both sides need to negotiate some basic parameters, like how much data they're willing to receive at once (the window size).

    The three-way handshake solves all of these problems simultaneously.

    The Three Steps

    Let's call our two parties the Client (your browser) and the Server (the web server). The client always initiates. Here is exactly what happens:

    ---

    Step 1: SYN (Client → Server)

    The client sends a special TCP packet called a SYN (short for "synchronize") to the server. This packet contains:

  • A flag indicating it's a SYN packet
  • A randomly chosen **Initial Sequence Number (ISN)** — let's call it `X`. This number is the client's starting point for sequencing its data. It's chosen randomly (rather than always starting at zero) for security reasons — to prevent certain types of attacks where a third party guesses what sequence numbers are in use.
  • The client is essentially saying: *"Hey, I want to establish a connection. I'll be starting my sequence numbering at X. Are you there and ready?"*

    ---

    Step 2: SYN-ACK (Server → Client)

    If the server is listening on that port and willing to accept the connection, it responds with a SYN-ACK packet. This single packet does two things at once:

  • It **acknowledges** the client's SYN by including an ACK number of `X + 1` (meaning: "I got your SYN, and I'm expecting byte X+1 next from you")
  • It sends its own **SYN** with its own randomly chosen Initial Sequence Number — let's call it `Y`
  • The server is saying: *"Got it! I acknowledge your starting sequence number X. I'll be starting my own sequence numbering at Y. Here's my SYN — can you acknowledge mine?"*

    ---

    Step 3: ACK (Client → Server)

    The client receives the SYN-ACK and sends back a final ACK (acknowledgment) packet. This packet contains an ACK number of `Y + 1` (meaning: "I got your SYN, and I'm expecting byte Y+1 next from you").

    The client is saying: *"Got it! I acknowledge your starting sequence number Y. We're all set — let's go!"*

    ---

    After this third step, the connection is established. Both sides know the other is reachable and ready. Both sides have exchanged and acknowledged their initial sequence numbers. Now the actual data transfer can begin.

    Why Three Steps? Why Not Two or Four?

    This is a great question, and the answer reveals how cleverly the handshake was designed.

    Could we do it in two steps? The server could send a SYN+ACK and consider the connection open. But the problem is the server has no confirmation that the client received its SYN-ACK. From the server's perspective, it sent a SYN-ACK and just... waited. It doesn't know if the client is still there.

    Could we do it in four steps? Technically, the SYN-ACK in step 2 could be split into a separate ACK and a separate SYN. But combining them into one packet is simply more efficient.

    Three steps is the minimum number required for both sides to confirm that both sides can send and receive. This is a fundamental insight in the theory of reliable communications. It's so fundamental that protocol designers have a term for it: the minimum necessary asymmetric acknowledgment. Three handshakes achieve mutual confirmation with the minimum number of round trips.

    Sequence Numbers and Why They Matter

    The sequence numbers established during the handshake are not just ceremonial — they're actively used throughout the entire connection.

    Every byte of data sent is tagged with a sequence number. When the receiver gets the data, it sends back an ACK containing the sequence number of the next byte it's expecting. If the sender doesn't receive an ACK within a certain time (the retransmission timeout), it assumes the packet was lost and resends it.

    This mechanism is what makes TCP reliable. No other transport protocol does this automatically. UDP, by comparison, just fires packets into the void and hopes for the best.

    The sequence numbers also allow the receiver to handle out-of-order delivery. The internet doesn't guarantee that packets take the same path or arrive in the same order they were sent. Packets from the same connection might go through completely different routers and arrive in any sequence. Because TCP numbers every byte, the receiver can buffer out-of-order packets and reassemble them correctly before passing the data to the application layer.

    SYN Floods: When Handshakes Become Weapons

    The three-way handshake has a famous vulnerability that bad actors have exploited for decades: the SYN flood attack.

    Here's how it works. When a server receives a SYN packet (Step 1), it allocates some memory to track the "half-open" connection and then waits for the client's final ACK (Step 3). If the ACK never comes, the server waits for a timeout before freeing that memory — typically several seconds.

    An attacker can exploit this by sending millions of SYN packets with fake (spoofed) source IP addresses. The server dutifully responds to each with a SYN-ACK and then waits... and waits... and waits. The memory allocated to all these half-open connections fills up. Eventually, the server can't accept any new legitimate connections. It's overwhelmed. This is a type of Denial of Service (DoS) attack.

    The solution most servers use today is called SYN cookies. Instead of allocating memory when it receives a SYN, the server encodes all the necessary information into the SYN-ACK itself (as a cryptographically generated sequence number). It only allocates memory when it receives the client's ACK with that valid cookie. This means SYN floods can't exhaust server memory because the server isn't allocating anything until it gets the ACK.

    TCP Connection Termination: The Four-Way Goodbye

    Just as connections are established with a handshake, they need to be closed cleanly. TCP uses a four-way goodbye (sometimes called a four-way teardown or FIN handshake):

    1. The side that wants to close sends a FIN (finish) packet.

    2. The other side sends an ACK acknowledging the FIN. But it may still have data to send, so the connection isn't fully closed yet.

    3. When the second side is done sending, it sends its own FIN.

    4. The first side sends a final ACK.

    Why four steps instead of three? Because TCP connections are full-duplex — each side has its own independent data stream in each direction. Each side must close its own stream independently. The server might need to send a little more data after receiving the client's FIN before it's ready to close.

    Seeing It In Real Life

    You can actually watch TCP handshakes happen in real time using a free tool called Wireshark, which captures and displays all the network traffic on your machine.

    Install Wireshark, start a capture, open any website in your browser, and then filter the capture by TCP. You'll see a stream of packets, and among them, clear as day, you'll see the SYN, SYN-ACK, and ACK packets that established the connection — followed by the actual HTTP data — followed by the FIN packets that closed it.

    Watching a handshake happen in real time on your own machine, for a website you just loaded, is a genuinely satisfying moment for anyone who's read about it and wants to see the theory in practice.

    The Bottom Line

    The TCP three-way handshake is a small, elegant piece of protocol design that solves a surprisingly tricky problem: how do two machines that have never communicated before establish a reliable, synchronized connection across an unreliable network?

    Three packets. SYN. SYN-ACK. ACK. That's it. And on top of that tiny foundation, the entire reliable internet is built.

    Every email you've sent. Every video you've streamed. Every banking transaction you've made. All of it started with two machines exchanging three packets and saying hello.