Before any data moves, both sides exchange and acknowledge starting sequence numbers: SYN, SYN-ACK, ACK.
TCP promises a *reliable, ordered byte stream* — but it runs over IP, which loses, reorders, and duplicates packets freely. To deliver on that promise, both sides must first agree on where the stream *starts*. That agreement is the three-way handshake: SYN, SYN-ACK, ACK. It costs exactly one round trip before the first byte of real data can flow.
TCP labels every byte with a sequence number so the receiver can reorder what arrives and detect what's missing. Each side picks its *own* starting sequence number (an ISN, chosen unpredictably for safety). The handshake exists so each side learns the other's starting number and confirms it was heard.
SYN flag set and its starting sequence number, say x. (Client: SYN-SENT.)SYN carrying *its* starting number y, plus an ACK of x+1 (the next byte it expects from the client). One packet does both jobs. (Server: SYN-RECEIVED.)ACK y+1. The connection is now ESTABLISHED and data can flow.Client Server
| --- SYN seq=x -----------> |
| <-- SYN-ACK seq=y ack=x+1 - |
| --- ACK ack=y+1 --------> |
| (ESTABLISHED) |FIN that the other ACKs — a four-way exchange — because one side may keep sending after the other is done.