TCP Handshake

Intuition

TCP does not start sending application bytes immediately. First, both endpoints need to agree that a connection exists and synchronize the first sequence numbers they will use. The three visible messages are SYN, SYN-ACK, and ACK.

How It Works

The client begins with an initial sequence number, here 1000, and sends SYN seq=1000. The server receives that segment, moves into SYN-RECEIVED, and replies with its own initial sequence number, 5000. Because a SYN consumes one sequence number, the server's reply acknowledges 1001, not 1000.

When the client receives SYN ACK seq=5000 ack=1001, it can move to ESTABLISHED. It still needs to acknowledge the server's SYN, so it sends ACK seq=1001 ack=5001. Once the server receives that final ACK, both sockets are established and application data can flow.

Step By Step

Using the default normal scenario:

  1. The server waits in LISTEN; the client starts in CLOSED.
  2. The client sends SYN seq=1000 and enters SYN-SENT.
  3. The server receives it, enters SYN-RECEIVED, and prepares ack=1001.
  4. The server sends SYN ACK seq=5000 ack=1001.
  5. The client receives that reply and enters ESTABLISHED.
  6. The client sends ACK seq=1001 ack=5001.
  7. The server receives the ACK and enters ESTABLISHED.

The alternate Lost SYN-ACK scenario shows the same state machine with one failure: the server's reply is lost. The client waits for a simplified timeout and retransmits the same SYN seq=1000; the server then repeats the same SYN-ACK.

Complexity

The happy path is constant time: three protocol segments and two endpoint state transitions. Retries add more segments, so the toy retry path grows with the number of retransmissions.

Edge Cases

Packet loss does not automatically create a new connection. A retransmitted SYN uses the same initial sequence number for the same connection attempt. TCP also has other paths, such as simultaneous open and connection teardown, but those are outside this first handshake trace.

Common Mistakes

Do not read the ACK number as "the byte I just received." It means "the next sequence number I expect from you." That is why acknowledging seq=1000 becomes ack=1001, and acknowledging seq=5000 becomes ack=5001.

A Note on Simplification

This is a deliberately small explainer, not a substitute for a full TCP implementation. It omits TCP options, receive windows, window scaling, real RTT/RTO estimation, SYN cookies, simultaneous open, teardown, congestion control, and operating-system socket queues so the core three-way state machine stays readable.