How it works
The explanation, with examples you can run.
UDP: just datagrams
UDP (RFC 768) adds little to IP: source and destination ports, a length and a checksum. Each datagram is sent on its own; it may be lost, duplicated or reordered, and the sender isn't told. There is no connection set-up, so the first packet can carry data. That suits DNS lookups (one question, one answer, retry if nothing comes back), real-time media and games (where late data is useless), and protocols that want to build their own reliability, like QUIC.
TCP: a reliable stream
TCP (RFC 9293) turns unreliable packets into an ordered, reliable stream of bytes between two endpoints:
- Handshake. The client sends SYN with its initial sequence number, the server answers SYN-ACK with its own, and the client sends ACK. That costs one round trip before data flows.
- Sequence numbers and acknowledgements. Every byte is numbered. The receiver acknowledges what it has received in order, and the sender retransmits anything not acknowledged in time or reported missing.
- Flow control. The receiver advertises a window: how much it can buffer. A slow reader makes the sender wait instead of being flooded.
- Teardown. Each side sends FIN when done. The side that closes first keeps the connection in TIME_WAIT for a while, so delayed packets can't confuse a new connection on the same ports.
Reliability has a cost: if one packet is lost, everything after it waits in the receiver's buffer until the retransmission arrives, even if it belongs to an unrelated request on the same connection. This is head-of-line blocking, and it is the main reason HTTP/3 runs over QUIC, which multiplexes independent streams over UDP so a loss on one stream doesn't stall the others.
Congestion control
Flow control protects the receiver; congestion control protects the network between. The sender keeps a congestion window, a limit on unacknowledged data in flight. RFC 5681 describes the classic algorithm:
- Slow start: begin with a small window (about 10 packets on modern systems) and roughly double it every round trip.
- Congestion avoidance: past a threshold, grow by about one packet per round trip.
- Back off on loss: a lost packet is taken as a sign of congestion, so the window is cut, typically in half.
Linux uses CUBIC by default, and Google's BBR estimates bandwidth and round-trip time instead of waiting for loss. All of them mean a new connection starts slow. That is why connection reuse (HTTP keep-alive, connection pools), a CDN close to the user, and fewer round trips matter more than raw bandwidth for most web traffic.
Ports and sockets
An IP address identifies a host; a port (0 to 65535) identifies an application on it. A TCP connection is identified by four values: source IP, source port, destination IP, destination port. A server listens on one port and accepts many connections, each with a different client address and port. Programs reach all of this through sockets, the operating system's interface to the network, which the Linux path explores with ss and strace.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.