학습 목표
UDP(User Datagram Protocol) 가 비연결·최선 전달(best-effort) 전송 서비스임을 설명할 수 있다.
UDP 헤더 필드(출발·목적 포트, 길이, 체크섬)와 세그먼트 구조를 읽을 수 있다.
TCP와 비교해 UDP가 적합한 상황(DNS, 실시간, QUIC)과 부적합한 상황을 구분할 수 있다.
dig, tcpdump로 UDP 53 트래픽을 확인할 수 있다.
문제 상황
- DNS 질의는 짧은 한 번인데 TCP handshake가 꼭 필요한가
- 연결 설정 비용이 응답 크기보다 클 수 있다
- VoIP·게임에서 패킷 하나가 유실됐다
- 재전송하면 지연이 더 나쁜 경우가 있다 — UDP는 보장하지 않는다
ss -ulnp에 STATE가 없다- TCP의
ESTABLISHED와 달리 UDP는 연결 상태가 없다
- TCP의
- HTTP/3·QUIC은 UDP 위에서 동작한다
- “UDP = 느슨하고 쓸모없다”와 모순처럼 보인다
전송 계층에서 포트·demux를 봤다. 이제 가볍게 보내는 프로토콜 UDP부터 본다.
1. UDP란
UDP는 IP 위에서 프로세스 간으로 데이터그램을 주고받는 전송 계층 프로토콜이다. RFC 768.
| 특성 | UDP |
|---|---|
| 연결 | 비연결 — handshake 없음 |
| 신뢰성 | 최선 전달 — 도착·순서·중복 보장 없음 |
| 흐름·혼잡 제어 | 없음 |
| 헤더 | 8바이트 고정 |
| 식별 | 출발·목적 포트 (demux) |
- 앱은
sendto()/recvfrom()— 매 패킷에 목적지 주소 지정 - 커널은 소켓 테이블에서 (dest IP, dest port, protocol)으로 demux — TCP와 달리 연결 큐 없음
- 손실·순서 뒤바뀜은 애플리케이션이 감수하거나 상위 프로토콜이 처리 (QUIC 등)
2. UDP 세그먼트 구조
UDP 헤더는 8바이트. 그 뒤에 애플리케이션 페이로드가 붙는다.

| 필드 | 크기 | 역할 |
|---|---|---|
| Source port | 16 bit | 송신 프로세스 (선택, 0 가능) |
| Destination port | 16 bit | 수신 프로세스 — demux 키 |
| Length | 16 bit | 헤더+데이터 전체 길이 (바이트) |
| Checksum | 16 bit | 오류 검출 (IPv4는 0=미사용 가능, IPv6는 필수) |
0 16 32
├─────────┬─────────┬─────────┬─────────┤
│ src port│ dst port│ length │checksum │
├─────────┴─────────┴─────────┴─────────┤
│ application payload │
└───────────────────────────────────────┘
- IP 패킷 안에 UDP 세그먼트가 실림 — 캡슐화 관점에서 segment (UDP PDU)
- MTU 초과 시 IP가 분할(fragment) 할 수 있음 — UDP 자체는 분할 안 함
- 체크섬은 헤더·데이터·의사 IP 헤더 포함 — 손상된 세그먼트 드롭 가능
3. 비연결 동작
TCP는 3-way handshake 후 send()/recv() 스트림을 쓴다. UDP는 준비 없이 데이터그램을 낸다.

Client Server
| UDP datagram (sport, dport, payload) |
|--------------------------------------->|
| optional reply datagram |
|<---------------------------------------|
- 상태 없음 — 커널에 “이 연결” 레코드가 없어
ss에 ESTABLISHED가 안 보임 - 독립적 데이터그램 — 각 패킷이 별도 라우팅·처리 (순서 보장 없음)
- 양방향 가능 — 서버가 클라 주소를 알면 같은 소켓으로 응답 (
recvfrom이 주소 반환) - Connection refused — 목적 포트에 수신 소켓이 없으면 ICMP port unreachable (OS·방화벽에 따라)
# DNS 질의 — UDP 53
dig @8.8.8.8 example.com A +stats
# Query time · SERVER: 8.8.8.8#53(UDP)
# UDP 패킷 캡처 (짧게)
sudo tcpdump -i any -n udp port 53 -c 4
4. UDP의 한계 (의도된 트레이드오프)
UDP가 안 해 주는 것은 버그가 아니라 설계 선택이다.
| 없는 기능 | 결과 |
|---|---|
| 재전송 | 패킷 유실 시 앱이 모름 (unless app checks) |
| 순서 보장 | 뒤늦게 도착한 패킷이 앞선 것보다 먼저 처리될 수 있음 |
| 중복 제거 | 같은 데이터그램이 두 번 올 수 있음 |
| 흐름 제어 | 빠른 송신이 수신 버퍼를 넘길 수 있음 — 앱·OS가 드롭 |
| 혼잡 제어 | 네트워크 혼잡 시 무분별 전송 → 다른 트래픽 악화 가능 |
- 신뢰·순서가 필요하면 TCP 또는 앱/QUIC이 직접 구현
- 실시간은 오래된 프레임 버리기가 재전송보다 나을 때가 많음
- 대용량 파일·API는 TCP(또는 QUIC)가 일반적
5. UDP vs TCP — 언제 무엇을 쓰나
| UDP | TCP | |
|---|---|---|
| 연결 | 없음 | handshake |
| 전달 | best-effort | 신뢰·순서 |
| 오버헤드 | 8B 헤더 | 헤더+상태·윈도 |
| 지연 | setup 짧음 | handshake·재전송으로 가변 |
| 적합 | 짧은 질의, 실시간, 커스텀 프로토콜 | HTTP, SSH, DB, 대부분 API |

| 사례 | UDP를 쓰는 이유 |
|---|---|
| DNS | 질의·응답이 작고 한 번 — 53/UDP 기본 (큰 응답·DNSSEC는 TCP도) |
| VoIP·화상 | 일부 손실 허용, 낮은 지연 우선 |
| 게임·라이브 | 최신 상태가 중요, 재전송 지연 회피 |
| DHCP·SNMP·NTP | 브로드캐스트/멀티캐스트·짧은 메시지 |
| QUIC / HTTP/3 | UDP 위에 TLS·신뢰성·멀티플렉싱 직접 구현 |
- QUIC은 “UDP로 TCP를 흉내”가 아니라 새 전송 설계 — NAT·방화벽 통과에 UDP 포트 활용
- 앱이 UDP를 선택했다면 무엇을 포기했는지(신뢰성·순서)를 알고 있어야 한다
6. 소켓 API 관점
// UDP server (conceptual)
int fd = socket(AF_INET, SOCK_DGRAM, 0);
bind(fd, ...); // port 53, 123, etc.
recvfrom(fd, buf, len, 0, &client_addr, &addrlen);
sendto(fd, reply, rlen, 0, &client_addr, addrlen);
# UDP 소켓을 연 프로세스
ss -ulnp
# State Recv-Q ... Local Address:Port Process
# (UDP는 TCP처럼 state 컬럼이 비어 있거나 UNCONN)
SOCK_DGRAM→ UDP,SOCK_STREAM→ TCP- 버퍼는 OS가 관리 —
recvfrom이 느리면 드롭 (TCP는 흐름 제어로 밀어냄) - OS 시리즈의 fd·read/write와 동일하게 소켓도 파일 디스크립터
7. 정리
- UDP는 비연결·최선 전달 — 8바이트 헤더, 포트로 demux
- 신뢰·순서·혼잡 제어 없음 — 필요하면 TCP 또는 QUIC·앱 로직
- DNS·실시간·QUIC처럼 지연·단순성이 이득일 때 선택
- 다음에는 연결 지향인 TCP — handshake와 신뢰성
다음에 다룰 것
- TCP 기초
- 3-way handshake, 연결 지향, 신뢰적 전달
해당 내용은 Computer Networking: A Top-Down Approach, 8/E (James Kurose, Keith Ross) 의 내용을 기반으로 합니다.