In TCP, what is the difference between a port and a socket, and how can one listening port serve thousands of clients at once?
answer
- number versus address-plus-number
- a connection is a pair of sockets
- protocol, two addresses, two ports
- the listener never changes ports
basics
~20 sA TCP port is a 16-bit number on a host; a socket is an IP address plus a port. A connection is a pair of sockets, so one server port holds many connections differing by client address or port.
solid answer
~50 sA **port** is a 16-bit number (0-65535) carried in the TCP header so one host can demultiplex traffic among its applications. RFC 9293 defines a **socket** as an IP address concatenated with a port, and a **connection** as a *pair* of sockets. Add the protocol and you get the **5-tuple** `{protocol, local IP, local port, remote IP, remote port}` that RFC 6056 says must be unique. A server's listening socket fixes only the local half; every accepted connection shares the same local port but differs in client address or client port, so the stack keeps separate state for each while the listener stays in LISTEN. One client address can hold at most one connection per client port toward that server socket, more client addresses multiply that, and the practical ceiling is per-connection memory and descriptors, not the port number.
go deeper
Recall the three definitions cleanly: a port is a number, a socket is an address plus a port, a connection is a pair of sockets. Then say why one server port can serve many clients.
Name the 5-tuple and do the arithmetic: per client address one connection per client port, more client addresses multiply the space, so the listening port itself is never the bottleneck.
Say what the real ceilings are — per-connection memory, descriptor limits, and the client's ephemeral range toward one destination — and distinguish the protocol's socket from the API's socket handle.
Connect the tuple to capacity planning: budget connections by per-connection state and by how many distinct client sockets reach you, not by port numbers, and remember that stateful middleboxes key their flow state on the same tuple.
## Ports: the number that demultiplexes A **port** is a 16-bit unsigned field in both the TCP and the UDP header, so it ranges from `0` to `65535`. Its job is **demultiplexing**: an IP address gets a packet to the right host, and the port gets the payload to the right application on that host. Every TCP segment carries two ports, a **source port** and a **destination port**. A port on its own does not identify anything outside the host. Port `443` exists on millions of machines at once. ## Sockets: an address plus a port RFC 9293's glossary defines a **socket** as "an address that specifically includes a port identifier, that is, the concatenation of an Internet Address with a TCP port". So `192.0.2.10:443` is a socket in the protocol's sense. The word has a second meaning that causes most of the confusion in interviews: - In the **protocol**, a socket is an *endpoint name*: address plus port. - In the **socket API**, a socket is a *handle* an application holds, created by `socket()`. A listening handle and each accepted connection handle are different sockets in this sense, even though they share the same local address and port. Good answers say which meaning they use. ## Connections: a pair of sockets, the 5-tuple RFC 9293 (Section 3.4.1) states that "a connection is defined by a pair of sockets". Adding the transport protocol gives the **5-tuple** that RFC 6056 (Section 2.2) uses as the instance identifier: `{protocol, local IP address, local port, remote IP address, remote port}` The rule that matters is **uniqueness of the whole tuple**, not of any single field. Two connections may share four of the five values as long as one differs. | Handle in the socket API | Local socket | Remote socket | TCP state | |---|---|---|---| | Listening socket | `192.0.2.10:443` | unspecified (any) | LISTEN | | Connection from client A | `192.0.2.10:443` | `198.51.100.7:50123` | ESTABLISHED | | Connection from client A, second tab | `192.0.2.10:443` | `198.51.100.7:50124` | ESTABLISHED | | Connection from client B | `192.0.2.10:443` | `203.0.113.9:50123` | ESTABLISHED | All four rows use local port `443`. The last three are distinct connections because their remote sockets differ, and the first is the passive open that RFC 9293 describes as waiting "for any call" with an unspecified remote socket. ## Why one listening port serves thousands of clients When a SYN arrives for `192.0.2.10:443`, the stack looks for an existing connection with that exact 5-tuple. If none exists and a socket is listening, it creates **new connection state** for that tuple. The listener itself is not consumed; it stays in LISTEN and keeps receiving new SYNs. The arithmetic, for one server socket: 1. From **one client address**, each connection needs a different client port, so the client can hold at most one connection per port it is able to use — bounded by its ephemeral range, tens of thousands at most. 2. From **many client addresses**, those spaces multiply. For IPv4 the theoretical number of distinct remote sockets is about 2^32 addresses times 2^16 ports. 3. The **real ceiling** is therefore not the port. It is the memory each connection's state and buffers take, the number of descriptors the process may hold, and CPU. So "a server can only handle 65,535 clients because there are 65,535 ports" is wrong twice: the server does not spend a port per client, and the limit that matters lives elsewhere. ## Misconceptions worth naming - **"The server moves each client to a new port."** It does not. Every accepted TCP connection keeps the listening port as its local port; only the remote half differs. - **"A port can carry one connection at a time."** One *5-tuple* can exist once at a time. A port participates in as many tuples as there are distinct remote sockets. - **"The destination port identifies the connection."** It identifies the service; the connection needs all five values. - **"A UDP socket works the same way."** UDP has no connections in the protocol. A bound UDP socket receives datagrams from any peer on one handle; there is no per-client state to create. ## Where this shows up Per-connection state is keyed on the same tuple: the host's own connection table, and stateful middleboxes in the path that track flows. Understanding that the tuple, not the port, is the identity is what lets you reason about connection limits, about why clients need many source ports toward one server, and about why the listening port never runs out.
- Can two worker processes on one host each hold TCP connections whose local port is 443 at the same time?Yes. Accepted connections all keep local port 443 and differ by their remote socket, so any number of them, spread over any number of processes, can coexist; the protocol only forbids two connections with the same full 5-tuple. Whether two separate *listening* sockets may bind the same address and port is decided by the socket API and its options, not by TCP.
- Does a TCP client have to call bind() before connect()?No. If the client skips `bind`, the stack fills in the local half at `connect` time: RFC 9293 says an unspecified local IP address on an active open is chosen by the host, and the stack picks an ephemeral port that makes the 5-tuple unique. Explicit `bind` is for when a client needs a specific source address, for example on a multihomed host, or a specific source port.
A company's main phone number is like a listening port: hundreds of calls can be in progress on it at once, because each call is identified by who is calling as well as the number they dialled. The published number never runs out; what runs out is the switchboard's capacity to hold calls.
saying these in an interview costs you the question
- Each accepted client is moved to its own new server port.
- A TCP port can carry only one connection at a time.
- A server runs out of connections after 65,535 clients because ports run out.
- A socket and a port are the same thing.
- The destination port alone identifies a TCP connection.