One address, many programs
Layer 3 delivers a packet to a host. That is not enough, because a host runs a web server, a database, an SSH daemon, and a browser at the same time. Layer 4 finishes the delivery to the right program, and the field it uses is the port, a 16 bit number from 0 to 65535.
The ranges are split by convention, and the split is registered with IANA.
| Range | Name | Who uses it |
|---|---|---|
| 0 to 1023 | well known | standard services, needs privilege to bind on Unix |
| 1024 to 49151 | registered | vendor services, databases, application servers |
| 49152 to 65535 | dynamic or ephemeral | the client side of every connection |
Ports worth knowing by heart, because they appear in firewall rules and captures constantly:
| Port | Protocol | Service |
|---|---|---|
| 22 | TCP | SSH |
| 25 | TCP | SMTP, mail transfer |
| 53 | UDP and TCP | DNS |
| 67, 68 | UDP | DHCP server, DHCP client |
| 80 | TCP | HTTP |
| 123 | UDP | NTP, time |
| 443 | TCP and UDP | HTTPS, and QUIC on UDP |
| 3306 | TCP | MySQL |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
A socket is the operating system's handle for one endpoint of a communication. A connected TCP socket is identified by five values, the five tuple:
(protocol, local IP, local port, remote IP, remote port)
All five together must be unique on the host. That is why 500 browser tabs can all reach port 443 on the same server, because each connection has a different local ephemeral port. A listening socket is different, it is identified by protocol, local IP, and local port only, and it has no remote end yet.
UDP: four fields and no promises
UDP (user datagram protocol) is the smaller of the two transports, and its entire header is 8 bytes.
| Field | Size | Purpose |
|---|---|---|
| Source port | 2 B | who sent it, may be 0 if no reply is wanted |
| Destination port | 2 B | which program receives it |
| Length | 2 B | header plus data, in bytes |
| Checksum | 2 B | optional in IPv4, mandatory in IPv6 |
That is the whole protocol. What it gives you is multiplexing by port and an optional integrity check. What it does not give you is everything else:
- No connection. There is no handshake, so the first packet carries data. - No acknowledgment, so a lost datagram is simply gone and nobody is told. - No ordering. Datagram 5 may arrive before datagram 4. - No duplicate suppression, no retransmission, no flow control, no congestion control. A UDP sender will happily flood a link until it melts, unless the application manages that itself.
UDP is called connectionless and unreliable, and neither word is an insult. It is a thin, honest wrapper around IP that adds ports and gets out of the way. Lesson 7-4 returns to the cases where that is exactly right.
Seeing sockets on your own machine
ss -tuln
Netid State Local Address:Port Peer Address:Port udp UNCONN 0.0.0.0:68 0.0.0.0:* udp UNCONN 127.0.0.53:53 0.0.0.0:* tcp LISTEN 127.0.0.1:5432 0.0.0.0:* tcp LISTEN 0.0.0.0:22 0.0.0.0:* tcp LISTEN [::]:443 [::]:*
The flags mean -t TCP, -u UDP, -l listening only, -n numeric so ports are
not translated to names. Drop the -l and you see established connections with
both ends filled in.
The local address column is the field people misread, and it causes a specific bug worth naming.
| Bound to | Reachable from |
|---|---|
127.0.0.1:5432 | this host only, over loopback |
0.0.0.0:22 | any address on any interface of this host |
[::]:443 | any IPv6 address, and usually IPv4 too via dual stack |
192.168.1.42:80 | only traffic arriving at that one address |
So the PostgreSQL line above will refuse every connection from another machine no matter how the firewall is configured, because it is bound to loopback. "Works on the server, connection refused from anywhere else" is almost always this line and not a network problem at all.
Which reminds us of the useful distinction between the two common failures. Connection refused means a packet reached the host and the host actively said no, so routing works and nothing is listening on that port. Connection timed out means nothing came back at all, so a firewall dropped it silently or the route is wrong. Lesson 9-4 builds this into the diagnostic ladder.