Can TCP and UDP Share the Same Port? Deep Dive into OS Port Management
This article explains why TCP and UDP can use the same numeric port, how client and server processes manage port sharing, and the role of socket options like SO_REUSEADDR and SO_REUSEPORT in enabling high‑availability and load‑balanced networking.
Problem Overview
Many interviewers ask whether TCP and UDP can use the same port. The answer is not a simple yes or no; it depends on the protocol layer, client or server role, and socket options.
1. Protocol Layer: TCP and UDP Port Spaces
TCP and UDP each have an independent set of 65536 ports (0‑65535). A port number on TCP does not interfere with the same number on UDP, just like two separate buildings each having rooms numbered 0‑65535.
TCP port 53 is used by DNS for zone transfers.
UDP port 53 is used by DNS for regular queries.
Both ports can be observed simultaneously with: netstat -tuln | grep :53 Result shows a TCP listener and a UDP listener on port 53, confirming they coexist.
2. Client TCP Processes
A TCP socket is uniquely identified by the four‑tuple source IP, source port, destination IP, destination port . Once a process binds to a source port on a given IP, no other process can bind to the same [IP:port] combination.
Example: If the browser uses 1.1.1.1:8888, that exact combination is exclusive.
After the connection closes, the socket enters TIME_WAIT (1‑4 minutes), during which the port remains unavailable.
Different local IPs (e.g., 1.1.1.1 vs 127.0.0.1) can each use the same port number because the OS tracks the full [IP:port] pair.
3. Client UDP Processes
UDP port usage has two distinct modes:
Unconnected UDP (no bind)
If a program sends data without calling bind(), the kernel assigns a temporary source port for that transmission only. The port is exclusive while sending but can be reused by other processes when idle.
// send without explicit bind
sendto(sock, data, len, 0, &server_addr, addr_len);Connected UDP (explicit bind)
When bind() is used, the chosen port is fully owned by the process until it closes the socket. Adding connect() records the remote address, making UDP behave more like TCP (fixed four‑tuple).
// explicit bind and connect
bind(sock, &local_addr, addr_len);
connect(sock, &server_addr, addr_len);
send(sock, "Hello", 5, 0);Choosing between unconnected and connected UDP depends on whether you need one‑way fire‑and‑forget traffic or reliable bidirectional communication.
4. Server TCP Processes
By default only one process can listen on a TCP port. The socket option SO_REUSEADDR relaxes this rule, allowing multiple processes to bind to the same port under specific conditions:
Processes may bind to the same port on different IP addresses.
The most specific binding wins. For example, if Process A binds to *:80 (all interfaces) and Process B binds to 2.2.2.2:80, connections to 2.2.2.2:80 go to Process B, while other IPs go to Process A.
This mechanism also enables automatic failover: if the interface bound by Process B fails, Process A (the wildcard listener) seamlessly takes over the traffic.
int sock = socket(AF_INET, SOCK_STREAM, 0);
int reuse = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));5. Server UDP Processes
UDP offers SO_REUSEPORT, which goes beyond SO_REUSEADDR by allowing multiple processes to bind to the *exact* same IP‑port pair. The kernel then distributes incoming packets using a hash of source/destination addresses and ports, providing:
Per‑client session affinity (the same client always hits the same process).
Load balancing across processes on multi‑core systems.
int sock = socket(AF_INET, SOCK_DGRAM, 0);
int reuse = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse));
bind(sock, &addr, sizeof(addr));For multicast or broadcast traffic, all processes that have bound the same multicast address receive a copy of each packet, which differs from the load‑balancing behavior of unicast UDP.
Conclusion
TCP and UDP maintain independent port tables, so the same numeric port can be used simultaneously.
On the client side, a TCP port is exclusive per [IP:port] pair; TIME_WAIT can delay reuse.
UDP ports can be shared when unbound, but become exclusive after bind().
Server‑side TCP can achieve high availability with SO_REUSEADDR and specific binding rules.
Server‑side UDP can achieve true port sharing and load balancing with SO_REUSEPORT, also supporting multicast scenarios.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
