Skip to main content

Lesson: TCP, UDP & Ports

What you'll learn

  • Why IP addresses alone aren't enough — and what a port adds.
  • The difference between TCP and UDP, and when each is the right choice.
  • What the TCP three-way handshake is and why "connection" means something specific.
  • How to read ss/netstat output to see what's listening and connected on a machine.

The lesson

1. The gap IP leaves

IP gets a packet to the right machine. But a machine runs many programs at once — a web server, an SSH daemon, a database. Which one should receive this packet? That's what ports solve. A port is a 16-bit number (0–65535) that identifies a specific program/service on a machine.

The full coordinate for a conversation is therefore IP address + port, often written 10.100.100.3:443:

10.100.100.3 : 443
└────┬─────┘  └┬┘
 which machine  which service on it (443 = HTTPS)

Some ports are conventional ("well-known"):

22   SSH        443  HTTPS       5432 PostgreSQL
80   HTTP       53   DNS         6379 Redis
3306 MySQL      9080 promtail    6443 Kubernetes API

These are conventions, not laws — but following them is what lets a browser "just know" to use 443 for https://.

2. The transport layer: TCP and UDP

Ports live in the transport layer, which sits on top of IP. Two protocols dominate it, and they make opposite trade-offs.

TCP — Transmission Control Protocolreliable, ordered, connection-based.

  • Guarantees delivery: lost packets are retransmitted.
  • Guarantees order: bytes arrive in the sequence they were sent.
  • Establishes a connection before any data flows.
  • Cost: more overhead and latency (acknowledgements, retransmits).
  • Use it when correctness matters: web (HTTP/HTTPS), SSH, databases, Git.

UDP — User Datagram Protocolfast, connectionless, best-effort.

  • No connection setup — just fire packets ("datagrams") at the destination.
  • No delivery or ordering guarantee — lost packets are simply gone.
  • Tiny overhead, very low latency.
  • Use it when speed beats perfection, or you handle reliability yourself: DNS lookups, video/voice streaming, some metrics/telemetry.
        TCP                              UDP
  ┌───────────────┐              ┌───────────────┐
  │ "Did you get  │              │ "Here's data."│
  │  that?" "Yes."│              │ (no reply      │
  │  reliable,    │              │  expected)     │
  │  ordered,     │              │  fast,         │
  │  slower       │              │  may drop      │
  └───────────────┘              └───────────────┘
   web, ssh, db                   dns, streaming

3. The TCP three-way handshake

"Connection-based" means TCP does a short negotiation before sending your data — the three-way handshake:

client ──── SYN ────▶ server     "I want to talk. Here's my starting sequence number."
client ◀── SYN-ACK ── server     "OK, I heard you. Here's mine."
client ──── ACK ────▶ server     "Great, I heard you too. Let's go."
   ↓
[ now actual data flows ]

If you've ever seen "connection refused" vs "connection timed out", this is why:

  • Connection refused → the machine answered, but nothing is listening on that port (it actively said "no").
  • Connection timed out → no answer at all — wrong address, a firewall silently dropping packets, or the host is down.

That distinction is one of the most useful troubleshooting signals you'll learn, and it ties straight into the next chapter.

4. Listening vs connected

A server listens on a port (waits for incoming connections). A client opens a connection from a random high port to the server's well-known port. So one running service has:

  • one listening socket (e.g. 0.0.0.0:443), plus
  • one established socket per active client connection.

5. See it on the lab

ss -tlnp        # TCP (t) listening (l) sockets, numeric (n), with process (p) — what's serving here?
ss -tunp        # TCP + UDP, all sockets
ss -tn state established   # current live TCP connections

# Prove a port is reachable from another machine (e.g. from the Jumpbox to Docs-Server):
nc -vz 10.100.100.3 443    # "succeeded" = something is listening; "refused"/timeout = not
curl -v http://10.100.100.2:3000   # watch the connection get established, then the HTTP request

Run ss -tlnp on the Git-Server and you'll literally see Gitea listening on :3000 — the abstract "service on a port" made real.


Dig deeper

  • Cloudflare Learning — What is TCP/IP?: https://www.cloudflare.com/learning/ddos/glossary/tcp-ip/
  • Cloudflare Learning — UDP vs TCP: https://www.cloudflare.com/learning/ddos/glossary/user-datagram-protocol-udp/
  • PracticalNetworking — Packet Traveling (ties IP + ports + delivery together): https://www.practicalnetworking.net/series/packet-traveling/packet-traveling/
  • ss manual page (man7.org): https://man7.org/linux/man-pages/man8/ss.8.html

Search terms

  • TCP vs UDP explained when to use
  • TCP three way handshake explained
  • what is a network port number
  • connection refused vs connection timed out difference
  • ss command examples linux listening ports

Check yourself

  1. What does a port number add that an IP address alone cannot provide?
  2. Give two protocols/services that use TCP and two that use UDP, and say why each fits.
  3. Walk through the three-way handshake. What is each of SYN, SYN-ACK, ACK saying?
  4. You try to connect and get "connection refused." What does that tell you vs. a timeout?
  5. What command would you run to see every TCP port a machine is listening on, with the owning process?