StringMash.com

TCP three-way handshake

SYN, SYN-ACK, ACK, and the close, with your own sequence numbers.

8 characters
Updates as you type
Segments1. Client → Server <SEQ=100><CTL=SYN> 2. Server → Client <SEQ=300><ACK=101><CTL=SYN,ACK> 3. Client → Server <SEQ=101><ACK=301><CTL=ACK>
HandshakeSYN 100, SYN-ACK 300 ack 101, ACK 101 ack 301
The animation is below

Show the steps
ClientServerCLOSEDLISTENSYNseq 100SYN-SENTSYN-RECEIVEDSYN, ACKseq 300 ack 101ESTABLISHEDSYN-RECEIVEDACKseq 101 ack 301ESTABLISHEDESTABLISHED
  1. Start: client CLOSED, server LISTEN.
  2. 1. <SEQ=100><CTL=SYN> The client asks to connect. SYN carries its initial sequence number, 100. Now client SYN-SENT, server SYN-RECEIVED.
  3. 2. <SEQ=300><ACK=101><CTL=SYN,ACK> The server agrees and sends its own initial number, 300. ACK 101 says it expects 101 next: the SYN used up 100. Now client ESTABLISHED, server SYN-RECEIVED.
  4. 3. <SEQ=101><ACK=301><CTL=ACK> The client acknowledges the server's SYN with ACK 301. Both sides are now ESTABLISHED. Now client ESTABLISHED, server ESTABLISHED.

Watch the segments

Type two sequence numbers above to see the connection.

Using it

Type two numbers: the initial sequence number the client picks, then the server's. The sample, 100 and 300, is the example RFC 9293 uses, so the segments match its figures line for line. Show switches between the handshake, a whole connection (add a third number to send that many bytes in the middle), and the close on its own.

The animation below plays one segment at a time, with each side's state after it arrives. Segments are written the way the RFC writes them: <SEQ=101><ACK=301><CTL=ACK>.

The three steps

SYN: the client sends a segment with the SYN flag set and its initial sequence number, say 100. It moves to SYN-SENT.

SYN-ACK: the server replies with SYN and ACK both set. Its own sequence number is its initial number, 300, and its acknowledgement number is 101. An ACK number always means "the next number I expect", and the SYN used up 100, so the next is 101.

ACK: the client acknowledges the server's SYN with ACK 301, its own sequence number now 101. Both sides are ESTABLISHED and data can flow. Each side has told the other its starting number, and each has heard the other confirm it.

Why three, not two

RFC 9293 gives the main reason: to stop old duplicate connection requests from causing confusion. A SYN delayed in the network from a connection long gone could arrive at a server. With only two steps the server would open a connection nobody wanted. With three, the server's SYN-ACK goes to the client, which sees it acknowledges a SYN it didn't just send, and refuses it.

It's also the fewest messages that let both sides check the other received their starting number: each SYN needs its own acknowledgement, and the server's SYN and ACK travel together.

Sequence numbers

Every byte TCP sends has a number, and the sequence number on a segment is the number of its first byte. SYN and FIN count as one each, though they carry no data, which is why acknowledging a SYN adds 1. Send 50 bytes starting at 101 and they're numbered 101 to 150; the receiver answers ACK 151.

The starting numbers aren't 0 or 1. RFC 9293 requires them to come from a clock-driven generator mixed with a secret hash of the connection's addresses and ports, so someone outside can't guess them and inject segments. Wireshark shows "relative" numbers starting at 0 to make captures readable; the real ones are large and look random. The numbers are 32 bits, so they wrap round to 0 after 4,294,967,295.

The states you'll see

StateMeans
LISTENThe server is waiting for a connection request.
SYN-SENTThe client has sent SYN and waits for SYN-ACK.
SYN-RECEIVEDThe server has had a SYN, sent SYN-ACK, and waits for the ACK.
ESTABLISHEDOpen: data can flow both ways.
FIN-WAIT-1This side sent FIN and waits for it to be acknowledged.
FIN-WAIT-2Its FIN was acknowledged; it waits for the other side's FIN.
CLOSE-WAITThe other side has closed; this side can still send until it closes too.
LAST-ACKThis side sent its FIN after the other's, and waits for the last ACK.
TIME-WAITWaiting twice the maximum segment lifetime before closing for good.
CLOSEDNo connection.

Closing: four segments, not three

Each direction closes on its own. The side that's finished sends FIN; the other acknowledges it, but may still have data to send, so its own FIN can come later. That makes four segments, though the middle two are often sent together.

The side that closed first then waits in TIME-WAIT for twice the maximum segment lifetime, 2 MSL. RFC 9293 sets MSL at 2 minutes as an engineering choice. The wait means a lost final ACK can be resent when the other side repeats its FIN, and stray segments from this connection die out before a new one reuses the same addresses and ports.

Questions

Is it SYN, SYN-ACK, ACK?

Yes. The middle segment has both the SYN and ACK flags set, so it's usually called SYN-ACK. RFC 9293 writes it <CTL=SYN,ACK>.

What happens if both sides send SYN at the same time?

TCP handles it: each side gets the other's SYN while in SYN-SENT, answers with SYN-ACK, and both reach ESTABLISHED. RFC 9293 draws it as its Figure 7. It's rare in practice, so this page shows the usual client and server case.

Where can I see the real segments?

Capture a connection in Wireshark or with tcpdump and paste a packet's bytes into the TCP/IP header decoder. The flags field shows SYN, ACK and FIN, and the sequence and acknowledgement numbers follow the pattern on this page.

Why does the animation only go up to 3 steps a second?

Each step adds an arrow and recolours the current one. The web's accessibility guidelines allow anything that flashes three flashes a second at most, and capping the animation at three steps a second keeps it inside that.

Sources

Added . What's new