LinuxXIX · Networking FoundationsTCP/UDP
TCP and UDP - transport-layer essentials
What you'll learn
- Describe the three-way handshake and four-way close
- Identify TCP states a sysadmin sees in production
- Explain when to choose UDP and when to choose TCP
- Use ss to inspect TCP and UDP sockets
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09
TCP and UDP are the two transport protocols a sysadmin deals with daily. TCP gives you a reliable, ordered byte stream; UDP gives you a datagram with no guarantees. Picking the right one is a design decision, not an accident.
TCP at a glance
TCP provides:
- Connection-oriented: a session exists between two endpoints.
- Reliable delivery: lost packets are retransmitted.
- Ordered: bytes arrive in the order they were sent.
- Flow-controlled: the receiver tells the sender how much data it can accept.
- Congestion-controlled: the sender slows down when the network is congested.
These guarantees come at a cost: TCP carries a 20-byte header at minimum — and more in practice, because timestamps, SACK and window scale are options that live past those 20 bytes — requires state at both ends, and adds round-trip latency for the handshake and acknowledgements. UDP’s header is 8 bytes.
That 20 is a number you use, not trivia. With a 20-byte IPv4 header it gives an MSS of 1460 on a standard 1500-byte path, which is the arithmetic behind every tunnel you size and every MSS clamp you write. Over IPv6 the fixed header is 40 bytes, so the same path gives 1440. Get the header size wrong and the clamp is wrong, which shows up as a connection that completes its handshake and then hangs on the first full-size packet.
The three-way handshake
Every TCP connection starts with:
Client -> Server: SYN (seq=x)
Server -> Client: SYN,ACK (seq=y, ack=x+1)
Client -> Server: ACK (seq=x+1, ack=y+1)
After the third packet, both sides can send data. The handshake is visible in the network and in the connection state.
TCP connection states
A TCP connection on a Linux host is always in one of these states:
| State | Meaning |
|---|---|
| LISTEN | Server is waiting for a connection |
| SYN-SENT | Client sent SYN, waiting for response |
| SYN-RECEIVED | Server received SYN, sent SYN-ACK |
| ESTABLISHED | Connection is open, data can flow |
| FIN-WAIT-1 | Local side sent FIN |
| FIN-WAIT-2 | Local side got ACK of its FIN |
| CLOSE-WAIT | Remote side sent FIN, local side has not closed |
| LAST-ACK | Local side sent FIN, waiting for final ACK |
| TIME-WAIT | Local side sent FIN, got ACK, waiting for stray packets |
| CLOSE-ING | Both sides sent FIN simultaneously |
| CLOSED | No connection |
The states a sysadmin sees most often are LISTEN (server sockets), ESTABLISHED (active connections), TIME-WAIT (recently closed connections), and CLOSE-WAIT (a bug - the application is not closing its end).
Inspect with ss
ss -t # all TCP sockets
ss -l # only listening
ss -tn # TCP, no name resolution (faster)
ss -ltn # listening TCP, numeric
ss -s # summary statistics
ss -tnp # TCP, numeric, with process info
ss -tn state established
ss -tn state time-wait | head
ss -tlnp 'sport = :443'
ss replaced the older netstat. It reads directly from
kernel data structures and is fast even on hosts with tens of
thousands of connections.
Example output:
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:443 0.0.0.0:*
ESTAB 0 0 10.0.0.10:443 10.0.0.5:51234
TIME-WAIT 0 0 10.0.0.10:443 10.0.0.6:49812
Recv-Q and Send-Q show the queued bytes. A non-zero
Recv-Q on ESTABLISHED means the application is not draining
the receive buffer - a problem to investigate.
UDP at a glance
UDP is the opposite of TCP:
- Connectionless: each datagram stands alone.
- Unreliable: lost packets are not retransmitted.
- Unordered: datagrams may arrive out of order or not at all.
- No flow or congestion control: the sender pushes at full rate.
UDP is used for:
- DNS (most queries)
- NTP
- Syslog
- Video and voice (RTP)
- QUIC (modern HTTP/3)
- Service discovery (mDNS, Consul, etc.)
A common mistake is treating UDP like TCP and expecting retransmission. The application must handle loss.
UDP inspection
ss -u # all UDP sockets
ss -uln # listening UDP, numeric
ss -unp # UDP with process info
UDP sockets show in UNCONN state. There is no connection
state because there is no connection. To see UDP traffic
volume, use nstat or sar -n UDP.
TCP vs UDP: when to choose
| Use TCP when | Use UDP when |
|---|---|
| Data integrity matters | Small, frequent, loss-tolerant queries |
| Ordering matters | Real-time, where late data is useless |
| You want NAT-friendly state | You want minimal overhead |
| HTTP, SSH, databases, mail | DNS, NTP, syslog, voice, video, telemetry |
Knowledge check
Knowledge check · 3 questions
Q1. How many packets are exchanged in the TCP three-way handshake?
Q2. What does a CLOSE-WAIT state on a TCP connection indicate?
Q3. Which of the following protocols typically use UDP? Select all that apply.
Passing score: 75%. Answers are checked in this browser.