hop 20 of 32 · 6 min
TCP: making an unreliable network look reliable
IP makes no promises. Packets may be lost, duplicated, or arrive out of order. TCP takes that and presents an ordered, reliable byte stream, and every mechanism it has exists to bridge that gap.
Opening a connection
Client Server
| SYN, seq=x |
|------------------------------>|
| SYN-ACK, seq=y, ack=x+1 |
|<------------------------------|
| ACK, ack=y+1 |
|------------------------------>|Three messages, not two, because a connection is two independent streams and each direction needs its sequence number acknowledged. After two messages the client knows both arrived; the server does not yet know its own reply got through.
Sequence numbers and acknowledgements
Every byte is numbered. The receiver acknowledges the next byte it expects. A gap means something was lost, and three duplicate acknowledgements for the same byte tell the sender to resend immediately rather than wait for a timeout.
Flow control
The receiver advertises a window: how much it can accept right now. The sender may have that much unacknowledged data in flight and no more. This stops a fast sender drowning a slow receiver.
Throughput is limited by window divided by round trip time:
64 KB window, 100 ms RTT
524,288 bits / 0.1 s = about 5.2 MbpsOn a 100 Mbps link that uses 5 percent of it. This is the bandwidth-delay product, and it is why window scaling exists: filling that link needs a window of about 1.25 MB, far past what the original 16-bit field could express.
Congestion control
Flow control protects the receiver. Congestion control protects the network. TCP starts slow, doubles its rate each round trip until loss, then backs off sharply and grows carefully. Loss is treated as the signal that the network is full.