| Lesson 4 | Port numbers |
| Objective | Describe how a client process contacts its corresponding server process using port numbers. |
For a client/server transaction to occur, a client process on one machine must be able to reach a specific server process on another machine. An IP address alone identifies only the destination host, not the application running on that host. Modern operating systems solve this problem at the transport layer of the TCP/IP protocol suite by introducing port numbers.
Both TCP and UDP use 16-bit port numbers, allowing each protocol to support 65,536 distinct ports (0–65,535). Because TCP and UDP maintain separate port spaces, TCP port 443 and UDP port 443 represent two different endpoints.
The Internet Assigned Numbers Authority (IANA) categorizes port numbers into three ranges, each serving a distinct role in modern network communication:
In a typical web transaction, the server listens on a well-known port (such as TCP 443), while the client uses an ephemeral port chosen by the kernel.
In TCP/IP networking, a single connection is uniquely identified by a four-tuple:
Two connections are considered distinct if any one of these values differs. This model allows thousands of simultaneous client connections to reach the same server port without conflict.
A server application advertises its availability by listening on a specific port. On Linux, this involves registering the service with the kernel through the socket API. The kernel then routes incoming network traffic destined for that port to the appropriate process.
When a server uses TCP, it typically follows this high-level sequence:
socket() → bind() → listen() → accept()
The socket() system call creates a communication endpoint and associates it
with a protocol family such as AF_INET (IPv4) or AF_INET6 (IPv6),
and a transport type such as SOCK_STREAM (TCP).
After creating a socket, the server binds it to a specific port using the
bind() system call. This operation associates the socket with a
sockaddr_in structure containing:
A server can bind to a single network interface or to all available interfaces.
Binding to INADDR_ANY allows the service to accept connections on
any configured IP address for the host.
If the requested port is already in use, or if permissions are insufficient,
the bind() call fails. Otherwise, the kernel reserves the port and
associates it exclusively with that server process.
In modern environments, port numbers operate alongside additional layers such as firewalls, NAT, and container networking. While ports still define service endpoints, access is often filtered or translated before traffic reaches the application.
Secure deployments increasingly favor encrypted protocols (such as HTTPS and SSH) and restrict exposed ports to the minimum necessary. Understanding how ports function at the transport layer remains essential for diagnosing connectivity issues, configuring firewalls, and designing secure Linux network services.