Thuta Learning
BasicDevOps & Toolsbeginner

Ports and Sockets

What you'll walk away with

  • Explain the core ideas behind Ports and Sockets
  • Read the diagram and trace how data actually moves through it
  • Run the sample code and verify its output

Build the mental model

A port number is not a physical thing. There is no socket on the back of your machine numbered 443. A port is a 16-bit integer in the transport header whose only job is demultiplexing: one IP address arrives at one machine, but that machine runs many programs, and the kernel needs a key to decide which one gets these bytes. The port is that key. IP gets the data to the right host; the port gets it to the right process on that host.

IANA divides the 65,536 values into three ranges. Well-known ports, 0 to 1023, are for standard services and on Unix require privilege to bind, which is why web servers historically started as root just to claim port 80. Registered ports, 1024 to 49151, are assigned to specific applications on request. Ephemeral ports, 49152 to 65535, are the pool the kernel draws from when your side of a connection needs a temporary source port — you never choose these, and the range varies by operating system.

The point people miss is that a port does not identify a connection. The 4-tuple does: source IP, source port, destination IP, destination port. That is what the kernel hashes to route an arriving segment to the right socket. This is why a web server holds thousands of simultaneous connections on port 443 alone — every one of them shares the same destination IP and destination port, but each has a distinct source IP and source port, so no two tuples collide. The classic wrong mental model is "one connection uses up a port"; the real limit is unique tuples, and that space is vastly larger than 65,536.

text
THE 4-TUPLE: WHAT ACTUALLY IDENTIFIES A CONNECTION
--------------------------------------------------
 ( src IP , src port , dst IP , dst port )
      |         |         |         |
      |         |         |         +-- which service (443 = https)
      |         |         +------------ which machine (the server)
      |         +---------------------- kernel-picked, per connection
      +-------------------------------- which machine (the client)

Three clients, ONE listening port on the server:

  203.0.113.7 :52001 ---+
                        |
  203.0.113.7 :52002 ---+---->  198.51.100.10 : 443
                        |         (one listening socket)
  203.0.113.9 :52001 ---+

Server-side connection table:

  src ip        src port   dst ip           dst port   conn
  -----------   --------   --------------   --------   ----
  203.0.113.7      52001   198.51.100.10         443    #1
  203.0.113.7      52002   198.51.100.10         443    #2
  203.0.113.9      52001   198.51.100.10         443    #3

The right-hand columns are IDENTICAL on every row. The tuples
still differ, so the kernel never confuses one conn for another.

Port ranges (IANA):
  0     - 1023    well-known   privileged to bind on Unix
  1024  - 49151   registered   assigned on request
  49152 - 65535   ephemeral    kernel picks your source port

Connect it to a real scenario

Consider a load balancer terminating 20,000 HTTPS connections. Every one of them has destination port 443 and the same destination IP, and none of them interfere with each other. Each arriving segment carries a source IP and source port, and the kernel looks up the full 4-tuple to find the right socket. The listening socket on 443 is a fifth thing entirely — it only accepts new connections; established ones live in their own entries and are matched by tuple, not by port.

Where the tuple does bite you is on the client side. A machine opening many outbound connections to the same destination is constrained by its ephemeral port range, because with source IP, destination IP, and destination port all fixed, the source port is the only field left to vary — roughly 28,000 concurrent connections on a default Linux range. This is exactly the "cannot assign requested address" error people hit during load testing, and the fixes follow directly from the tuple: widen the ephemeral range, add source IPs to vary another field, or reduce lingering TIME_WAIT sockets.

The code below builds several 4-tuples that share one destination, shows that they remain distinct, and classifies a handful of port numbers into the IANA ranges.

Try the working example

python
# IANA port ranges. No sockets are opened here -- this is pure arithmetic
# over numbers that the kernel would use as demultiplexing keys.
RANGES = (
    (0, 1023, "well-known"),
    (1024, 49151, "registered"),
    (49152, 65535, "ephemeral"),
)


def classify(port):
    if not 0 <= port <= 65535:
        raise ValueError("a port is a 16-bit number: %d" % port)
    for low, high, name in RANGES:
        if low <= port <= high:
            return name


def fmt(conn):
    return "%s:%-5d -> %s:%d" % conn


# Four connections all arriving at the SAME server port.
connections = [
    ("203.0.113.7", 52001, "198.51.100.10", 443),
    ("203.0.113.7", 52002, "198.51.100.10", 443),
    ("203.0.113.9", 52001, "198.51.100.10", 443),
    ("203.0.113.9", 61000, "198.51.100.10", 443),
]

print("4-tuples seen by the server:")
for conn in connections:
    print("  ", fmt(conn))
print()

print("distinct 4-tuples      :", len(set(connections)))
print("distinct dst ip:port   :", len({(c[2], c[3]) for c in connections}))
print("=> one listening port, four independent connections")
print()

print("%-8s %s" % ("port", "range"))
print("-" * 24)
for port in (22, 80, 443, 3000, 8080, 52001, 65535):
    print("%-8d %s" % (port, classify(port)))
You should see
4-tuples seen by the server:
   203.0.113.7:52001 -> 198.51.100.10:443
   203.0.113.7:52002 -> 198.51.100.10:443
   203.0.113.9:52001 -> 198.51.100.10:443
   203.0.113.9:61000 -> 198.51.100.10:443

distinct 4-tuples      : 4
distinct dst ip:port   : 1
=> one listening port, four independent connections

port     range
------------------------
22       well-known
80       well-known
443      well-known
3000     registered
8080     registered
52001    ephemeral
65535    ephemeral

5-minute try-it

Add a second server to the connections list (for example one with destination port 80) and see how the distinct dst ip:port count changes. Then compute how many simultaneous connections one client can open to a single fixed destination using only the ephemeral range 49152-65535.

One important caution

Believing each connection consumes a port on the server — one server port carries thousands of connections; the real limits are distinct 4-tuples and file descriptors

Hard-coding the ephemeral range as 49152-65535 — the actual range is OS-specific (Linux defaults to 32768-60999), so classification and capacity math based on the IANA numbers can be wrong

IANA — Service Name and Transport Protocol Port Number RegistryComputer Networking

Easy traps

  • Believing each connection consumes a port on the server — one server port carries thousands of connections; the real limits are distinct 4-tuples and file descriptors
  • Hard-coding the ephemeral range as 49152-65535 — the actual range is OS-specific (Linux defaults to 32768-60999), so classification and capacity math based on the IANA numbers can be wrong
  • Validate sample code in a local or test environment before applying it to a production network.

Exercise

Add a second server to the connections list (for example one with destination port 80) and see how the distinct dst ip:port count changes. Then compute how many simultaneous connections one client can open to a single fixed destination using only the ephemeral range 49152-65535.

You'll know it worked when: 4-tuples seen by the server: 203.0.113.7:52001 -> 198.51.100.10:443 203.0.113.7:52002 -> 198.51.100.10:443 203.0.113.9:52001 -> 198.51.100.10:443 203.0.113.9:61000 -> 198.51.100.10:443 distinct 4-tuples : 4 distinct dst ip:port : 1 => one listening port, four independent connections port range ------------------------ 22 well-known 80 well-known 443 well-known 3000 registered 8080 registered 52001 ephemeral 65535 ephemeral

Ports and Sockets | Thuta Learning