Opening a connection
Before any data moves, the client asks to open a connection. Its SYN carries a starting sequence number, 1000 here. Real starting numbers are unpredictable, so leftover segments from an old connection, or forged ones, cannot pass as this one's.
The server agrees. Its SYN-ACK picks the server's own starting number, 5000, and acknowledges 1001: the next number it expects from the client. It also says its receive window: 400 bytes.
The client acknowledges 5001. That is the three-way handshake: both sides now know each other's starting numbers. After one round trip, the client can start sending.
Numbered bytes
The app hands TCP 500 bytes. TCP numbers every byte, 1001 to 1500, and cuts them into segments of 100. A segment's sequence number is the number of its first byte.
The server only has room for 400 bytes, the window it announced. So the client may have at most 400 bytes sent but not yet acknowledged. That is flow control: a fast sender cannot flood a slow receiver.
Loss and recovery
The client sends a full window: four segments, 1001 to 1400. A router drops 1101–1200; IP never promised delivery. The other three arrive, with a gap where 1101 should be.
For 1001–1100 the server replies ACK 1101, the next byte it expects. Bytes up to there are in order, so the app gets them. The client deletes its copy, and the window slides to 1101–1500.
The window moved forward by 100 bytes, so the client may send one more segment: 1401–1500. It still has not heard about 1101, and keeps its copy.
1201, 1301 and 1401 arrived while 1101 was missing. Now the server answers each one. The server can only ever ACK the next byte in order, so all three replies say ACK 1101 again.
Three duplicate ACKs mean "1101 is probably lost; later segments got through". The client resends 1101–1200 from its copy at once: fast retransmit. Without them, it would wait for its timer to run out.
The gap is filled, so the app gets 1101 to 1500 in order. One ACK 1501 covers all of it, because an ACK means "everything before this number". The client's send buffer is empty.
Closing
Each direction closes on its own. The client sends FIN, and the server ACKs it. When the server is done too, it sends its own FIN, and the client ACKs that. The connection is closed.
The segments, step by step
;; step 1/12 · syn ;; client → server TCP 192.0.2.7:51514 → 203.0.113.10:443 flags SYN seq 1000 (initial sequence number x; unpredictable in real life) why old or forged segments must not fit this connection (RFC 9293 §3.4.1, RFC 6528) win 65535, options: MSS 1460 header 20 bytes + options
Illustrative numbers: real initial sequence numbers are random 32-bit values (RFC 6528), segments usually carry up to 1460 bytes on Ethernet, and windows are many kilobytes. Events are grouped for clarity: on a real link the ACKs for 1201 and 1301 leave as soon as each segment arrives, before 1401 is even sent.