본문으로 건너뛰기
Previous
Next
UDP in Practice | Low Latency, DNS, Games, Streaming & QUIC

UDP in Practice | Low Latency, DNS, Games, Streaming & QUIC

UDP in Practice | Low Latency, DNS, Games, Streaming & QUIC

이 글의 핵심

Connectionless UDP: headers, checksums, ports, app-level reliability and ordering, and how HTTP/3 QUIC builds on UDP—realtime-focused guide.

Introduction

UDP (User Datagram Protocol) is a lightweight transport that sends datagrams without establishing a connection. TCP provides reliability, ordering, and congestion control; UDP only sendsloss, duplication, and reordering are handled by the application or upper layers (QUIC, RTP, …). That makes UDP common for DNS, realtime games, VoIP/video, and monitoring where latency or multicast matters. This article covers headers, ports, checksums, how retransmission and MTU work in practice, and how HTTP/3 / QUIC uses UDP.

After reading this post

  • Describe the UDP header and IPv4 vs IPv6 checksum rules
  • Implement basic datagram clients in C++, Python, and JavaScript with timeouts
  • Explain why games and streaming pick UDP from latency and throughput angles
  • Relate QUIC and WebRTC at a stack diagram level

Table of contents

  1. Protocol overview
  2. How it works
  3. Hands-on programming
  4. Performance characteristics
  5. Real-world use cases
  6. Optimization tips
  7. Common problems
  8. Wrap-up

Protocol overview

History and background

RFC 768 (1980) standardizes UDP—IP multiplexing via ports and optional checksumming with minimal philosophy: the internet is assumed unstable, and realtime needs a thin layer.

OSI placement

UDP is layer 4. IP reaches the host; UDP ports demux to sockets/processes. No connection state—each datagram is independent.

Core properties

PropertyDescription
ConnectionlessNo handshake (unless the app adds one).
UnreliableDrops and reordering are not repaired by UDP.
Datagram boundariesReceive size often matches send (OS buffering may split recv).
Multicast-friendlyEasier one-to-many patterns than TCP.
Low overhead8-byte header vs TCP.

How it works

Header (IPv4)

FieldSizeRole
Source port16 bitsSender port (optional).
Destination port16 bitsReceiver port.
Length16 bitsUDP header + payload length.
Checksum16 bitsOptional (0) on IPv4; mandatory on IPv6 UDP.

Checksum

IPv4 allows checksum disabled (0); IPv6 UDP requires checksums. Uses pseudo-header + UDP + payload. For stronger guarantees, add encryption and MAC at the app or TLS layer.

Ports

0–65535 demuxes processes on a host; well-known ports (e.g. DNS 53) are IANA-registered.

QUIC relationship (2026)

HTTP/3 uses QUIC over UDP. QUIC adds encryption, congestion control, streams, and connection migration—“simple UDP” vs “TCP-like reliability” in one modern stack.

flowchart TB
  subgraph app [Applications]
    H3[HTTP/3]
    RTP[RTP / realtime media]
    DNS[DNS client]
  end
  subgraph mid [Example stack]
    QUIC[QUIC + TLS]
    UDPR[UDP socket]
  end
  subgraph l3 [Network]
    IP[IP]
  end
  H3 --> QUIC
  QUIC --> UDPR
  RTP --> UDPR
  DNS --> UDPR
  UDPR --> IP

Hands-on programming

C++ (UDP client sketch)

// g++ -std=c++17 -O2 udp_client.cpp -o udp_client
#include <arpa/inet.h>
#include <cstring>
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
  const char* host = argc > 1 ? argv[1] : "127.0.0.1";
  const uint16_t port = argc > 2 ? static_cast<uint16_t>(std::stoi(argv[2])) : 5353;
  int fd = socket(AF_INET, SOCK_DGRAM, 0);
  if (fd < 0) { perror("socket"); return 1; }
  sockaddr_in peer{};
  peer.sin_family = AF_INET;
  peer.sin_port = htons(port);
  if (inet_pton(AF_INET, host, &peer.sin_addr) != 1) return 1;
  const std::string msg = "ping";
  if (sendto(fd, msg.data(), msg.size(), 0,
             reinterpret_cast<sockaddr*>(&peer), sizeof(peer)) < 0) {
    perror("sendto");
    close(fd);
    return 1;
  }
  char buf[2048];
  socklen_t plen = sizeof(peer);
  ssize_t n = recvfrom(fd, buf, sizeof(buf), 0,
                        reinterpret_cast<sockaddr*>(&peer), &plen);
  if (n < 0) { perror("recvfrom"); close(fd); return 1; }
  std::cout.write(buf, n);
  std::cout << '\n';
  close(fd);
  return 0;
}

Python 3

#!/usr/bin/env python3
import socket
import sys
def main() -> None:
    host = sys.argv[1] if len(sys.argv) > 1 else "127.0.0.1"
    port = int(sys.argv[2]) if len(sys.argv) > 2 else 5353
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.settimeout(3.0)
    try:
        sock.sendto(b"ping", (host, port))
        data, addr = sock.recvfrom(4096)
        print(f"from {addr}: {data!r}")
    except socket.timeout:
        print("timeout: no response", file=sys.stderr)
        raise SystemExit(1)
    finally:
        sock.close()
if __name__ == "__main__":
    main()

Node.js (dgram)

// node udp_client.mjs
import dgram from "node:dgram";
const host = process.argv[2] ?? "127.0.0.1";
const port = Number(process.argv[3] ?? 5353);
const socket = dgram.createSocket("udp4");
const onMessage = (msg, rinfo) => {
  console.log(`from ${rinfo.address}:${rinfo.port}: ${msg.toString()}`);
  socket.close();
};
socket.on("message", onMessage);
socket.on("error", (err) => {
  console.error(err.message);
  socket.close();
  process.exitCode = 1;
});
socket.send(Buffer.from("ping"), port, host, (err) => {
  if (err) {
    console.error(err.message);
    process.exitCode = 1;
    socket.close();
  }
});
setTimeout(() => {
  socket.close();
  console.error("timeout");
  process.exitCode = 1;
}, 3000).unref();

App-level reliability

Without TCP’s ACKs, request–response over UDP needs timeouts, retransmits with IDs, dedup, and backoff—or use QUIC/RTP that embed those concerns.

Performance characteristics

Latency

No handshake—you can send the first datagram immediately (firewalls/NAT aside). Important when time-to-first-packet dominates games and voice.

Throughput

UDP has no built-in windowed congestion control—you can flood, but you should not. Bulk transfer needs app congestion control or QUIC.

Overhead

8-byte UDP header—smaller than TCP until you add app/crypto headers.

Benchmarks

Loopback may hit hundreds of thousands of pps; on the internet, loss and jitter dominate games and voice more than raw Mbps.

Real-world use cases

DNS

Most queries use UDP; large responses may fall back to TCP.

Games

Latest state often beats retransmitting old stateUDP + app synchronization is common.

Realtime streaming

RTP typically runs on UDP; loss is handled with encoding, FEC, NACK, … WebRTC uses UDP—see the WebRTC guide.

Optimization tips

Packet size (MTU)

Design IP + UDP + payload under path MTU. Avoid IP fragmentation—loss costs a whole fragment chain.

Retransmit and ordering

  • Retransmit: measure RTT, handle jitter buffers, drop duplicates.
  • Ordering: sequence numbers; decide whether late packets are dropped or buffered.

Fairness

Uncontrolled UDP floods can harm neighbors and trigger ISP throttling. Rate limits and congestion control are operational requirements, not niceties.

Common problems

Loss

Common on Wi‑Fi, mobile, congested links—use FEC, lower bitrate, IFrame cadence, NACK/retransmit when delay allows.

Reordering

Multipath routing can reorder—use sequence numbers and reorder buffers, or stateless designs.

NAT and firewalls

UDP is stateless—NAT may expire mappings; keepalives, STUN/TURN (WebRTC), and QUIC keepalive address this.

Wrap-up

Summary

  • UDP favors low latency, simplicity, and multicast; reliability lives in the app or upper protocols.
  • DNS, games, and realtime media are classic UDP domains; HTTP/3/QUIC adds modern reliability on top.
  • MTU, timeouts, and retransmit policy are mandatory design topics.

When to choose UDP

  • Short requests, realtime, broadcast-style workloads—or QUIC/RTP. When reliability and ordering come first, start with the TCP guide; for browser P2P realtime, see WebRTC.

자주 묻는 질문 (FAQ)

Q. 이 내용을 실무에서 언제 쓰나요?

A. Connectionless UDP: headers, checksums, ports, app-level reliability and ordering, and how HTTP/3 QUIC builds on UDP—rea… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.

Q. 선행으로 읽으면 좋은 글은?

A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.

Q. 더 깊이 공부하려면?

A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.


같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.


이 글에서 다루는 키워드 (관련 검색어)

Network, UDP, Transport, Realtime, Streaming, QUIC, Socket 등으로 검색하시면 이 글이 도움이 됩니다.