A port is a 16-bit number (0–65535) that identifies a specific process or service on a machine. A socket is the combination of an IP address and a port — it’s the actual endpoint a connection talks to.
In simple language: an IP gets us to the right machine. A port gets us to the right app on that machine. Together they form a socket.
Why We Need Ports
Our laptop runs many things at once — browser, IDE, Spotify, Slack. They all share the same IP address. When a packet arrives, how does the OS know which app it’s for?
Ports. The OS routes incoming packets to the process that owns the matching port.
Port Ranges
0 – 1023 Well-known ports (need root/admin to bind)
1024 – 49151 Registered ports
49152 – 65535 Ephemeral / dynamic ports (used for outbound connections)
Well-Known Ports to Memorize
20, 21 FTP (data, control)
22 SSH
23 Telnet (avoid)
25 SMTP (email send)
53 DNS
80 HTTP
110 POP3
123 NTP (time sync)
143 IMAP
443 HTTPS
465/587 SMTPS / submission
993 IMAPS
995 POP3S
3306 MySQL
5432 PostgreSQL
6379 Redis
8080 Common alt-HTTP
27017 MongoDB
If asked “what port does X use?” — these are the safe bets.
Socket = IP + Port
Client socket: 192.168.1.5 : 51234
Server socket: 93.184.216.34 : 443
When our browser connects to example.com:443, the OS picks an ephemeral port (e.g. 51234) for our side. Now both ends have a socket.
The 5-Tuple — Connection Identity
A TCP connection is uniquely identified by five fields:
Two connections with any one of those values different = two distinct connections. That’s how a server can have thousands of clients all hitting :443 — they each have a unique source IP/port combo.
Multiple Browser Tabs to the Same Site
Open example.com in 3 tabs. We get 3 connections, all to 93.184.216.34:443, but with different source ports on our laptop:
1. 192.168.1.5:51234 -> 93.184.216.34:443
2. 192.168.1.5:51235 -> 93.184.216.34:443
3. 192.168.1.5:51236 -> 93.184.216.34:443
Server distinguishes them via the 5-tuple. Easy.
Listening vs Connected Sockets
A server socket has two states:
- LISTENING — bound to a port, waiting for connections (e.g.
0.0.0.0:80). - ESTABLISHED — an active connection with a specific client.
# See listening sockets
sudo lsof -iTCP -sTCP:LISTEN -P -n # macOS / Linux
ss -tlnp # Linux modern
netstat -an | grep LISTEN # cross-platform
A Tiny Socket in Code
Sockets are the API every language exposes for network I/O.
// Node.js — TCP server
const net = require('net');
const server = net.createServer((socket) => {
// socket is a connected socket with a 5-tuple
console.log('connected:', socket.remoteAddress, socket.remotePort);
socket.write('hello\n');
socket.end();
});
server.listen(3000, () => console.log('listening on :3000'));
# Python — TCP client
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP
s.connect(('example.com', 80))
s.sendall(b'GET / HTTP/1.0\r\nHost: example.com\r\n\r\n')
print(s.recv(4096).decode())
s.close()
Common Gotcha
Ports below 1024 require root/administrator privileges to bind. That’s why dev servers default to 3000, 5173, 8080 — no sudo needed. In production, the app usually binds to a high port and a reverse proxy (nginx/Caddy) listens on 80/443 and forwards.
Interview Tip
The 5-tuple is the cleanest way to answer “how does a server handle thousands of simultaneous clients on the same port?” — each connection is uniquely identified, so the OS keeps them straight.