Why UDP Drops Packets and How to Make It Reliable
This article explains UDP packet structure, why UDP lacks a send buffer, how fragmentation and buffer overflows cause packet loss, and presents practical solutions—including socket buffer tuning, delayed sending, retransmission strategies, redundancy, and RUDP—to achieve reliable communication over an inherently unreliable protocol.
1. UDP Packet Format
Each UDP packet consists of a header and a data section. The header contains four 16‑bit fields: source port, destination port, length, and checksum.
The packet format is illustrated below.
Field meanings:
Source Port: 16 bits, the sender's port.
Destination Port: 16 bits, the receiver's port.
Length: 16 bits, total size of the UDP packet (header + data) in bytes.
Checksum: 16 bits, error‑checking code.
2. UDP Fragmentation
2.1 Does UDP have a send buffer?
TCP provides both send and receive buffers; UDP provides only a receive buffer per socket and no send buffer. Data is transmitted immediately, and if the receive buffer is full the packet is discarded. UDP has no flow control, so a fast sender can easily overwhelm a slower receiver.
If a packet is split into fragments and any fragment is lost, the entire packet is discarded, which explains UDP's unreliability.
Conclusion
Each UDP socket has a receive buffer but no send buffer. When the receive buffer is full, new packets are dropped.
Detailed analysis
The Linux manual mentions a send‑buffer attribute for UDP sockets, but this refers to the kernel's output queue, not a true UDP send buffer. The textbook UNIX Network Programming shows diagrams where UDP’s send buffer is drawn as a dashed box, indicating it does not exist. UDP write succeeds when the packet reaches the link‑layer output queue.
2.2 UDP packet size
Optimal transmission size
The Ethernet MTU is 1500 bytes. Subtracting the IP header (20 bytes) and the UDP header (8 bytes) leaves 1472 bytes as the largest UDP payload that avoids IP fragmentation.
The theoretical maximum UDP payload is 65507 bytes, but sending such large packets is rarely optimal.
Fragmentation issues
Because UDP is unreliable, it is best to avoid IP‑level fragmentation. If the MTU is 1500 bytes and a client sends an 8000‑byte UDP packet, the receiver will obtain the full 8000 bytes only if all fragments arrive; otherwise recvfrom(9000) will block.
More fragments increase the probability of loss. If any fragment is missing, the whole packet is discarded.
3. Causes of UDP Packet Loss
Assuming no IP‑level fragment loss and no CRC error, the main loss reasons are:
3.1 Receive buffer overflow
If the socket’s receive buffer is full and the application cannot process incoming packets quickly enough, subsequent packets are dropped by the kernel.
Increasing the buffer size can mitigate this, but if the service is overloaded, merely enlarging the buffer may cause a cascade of timeouts.
3.2 Buffer too small for large packets
When a client sends a UDP packet larger than the socket’s receive buffer, the packet is lost. Setting the buffer to 64 KB solved this issue for the author.
int nRecvBuf = 32*1024; // set to 32 KB
setsockopt(s, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int));3.3 ARP cache expiration
If the ARP cache entry expires, the kernel queues up to three packets in the ARP queue; additional packets are dropped.
3.4 Long processing time on the receiver
If the receiver spends too much time processing a packet before calling recvfrom again, incoming packets may be lost. A common fix is to copy the packet to a queue and return to recvfrom immediately.
3.5 Oversized packets
Sending packets larger than about 50 KB without fragmentation can cause loss; such packets should be split into smaller chunks.
3.6 Excessive send rate
Even if each packet is smaller than the MTU, sending many packets back‑to‑back without pauses can cause loss. Introducing a small delay (e.g., usleep(1)) can help.
3.7 LAN vs. WAN loss
Loss is often higher on the public Internet. Splitting large packets and adding a pause can reduce loss, but at very high traffic volumes more sophisticated solutions are needed.
4. UDP Packet‑Loss Mitigation Strategies
4.1 Sender‑side: delayed sending
Applicable when the sender can be controlled and microsecond‑level delays are acceptable.
Insert a usleep(1) between sends to avoid overwhelming the receiver.
4.2 Receiver‑side: decouple reception from processing
Applicable when the sender’s rate cannot be controlled.
Use a worker thread and a queue: receive packets quickly with recvfrom, push them to a queue, and let another thread handle the data.
4.3 Receiver‑side: increase socket receive buffer
Use when the previous method still shows large loss.
int rcv_size = 1024*1024; // 1 MB
int optlen = sizeof(rcv_size);
int err = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&rcv_size, optlen);
// Verify with getsockopt; may need to raise net.core.rmem_max in /etc/sysctl.conf4.4 Application‑level reliability (ACK + retransmission + sequencing)
Implement an acknowledgement packet from the receiver. If the sender does not receive the ACK, it retransmits after a timeout. Include a unique sequence ID in each packet to detect loss and reorder packets.
4.5 Redundant transmission
Send two identical packets back‑to‑back (delay‑double‑send). Even with a 50 % loss rate, the receiver can reconstruct the original data.
4.6 Reliable UDP (RUDP)
RUDP adds reliability features (ACK, retransmission, congestion control) on top of UDP, useful for NAT traversal, weak‑network environments, bandwidth‑critical applications, and reducing resource consumption compared to TCP. Examples include QUIC and WebRTC.
5. When UDP Is the Right Choice
UDP excels in scenarios requiring high real‑time performance with low persistence, such as DNS queries, NTP, live audio/video, multiplayer games, and NAT traversal. It is also advantageous for multi‑point communication (e.g., group video calls) where TCP’s connection overhead and NAT issues are problematic.
6. UDP vs. TCP Efficiency
Although UDP is connection‑less and has lower per‑packet overhead, it cannot adapt to network conditions, lacks flow control, and may suffer from higher loss rates. Modern TCP implementations with proper tuning often achieve better throughput and resource utilization.
7. Practical Example: QQ Messaging
QQ uses UDP as the primary transport for client‑to‑client messages because it reduces server load and handles NAT traversal better than TCP. The client still maintains a TCP connection for login and presence, while UDP carries the actual chat data, with the server providing ACKs to ensure reliability.
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.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
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.
