UDP

Материал из llmdocs — справочник разработчика
UDP
Полное названиеUser Datagram Protocol
АвторДжон Постел
СпецификацияRFC 768 (1980)
Уровеньтранспортный
Размер заголовка8 байт
Гарантиинет — ни доставки, ни порядка, ни защиты от дубликатов
ПрименениеDNS, DHCP, NTP, VoIP и видеосвязь, игры, WireGuard, QUIC и HTTP/3

UDP (англ. User Datagram Protocol — протокол пользовательских датаграмм) — транспортный протокол стека TCP/IP, который отправляет отдельные сообщения — датаграммы — без установления соединения и без каких-либо гарантий: датаграмма может потеряться, прийти дважды или не по порядку, и протокол ничего с этим не делает. Взамен UDP прост, быстр и не добавляет задержек: никаких рукопожатий, подтверждений и повторных отправок.

UDP выбирают, когда опоздавшие данные бесполезны (голос, видео, игры), когда запрос и ответ умещаются в один пакет (DNS) или когда приложение хочет реализовать собственную надёжность поверх него, как QUIC.

История

Протокол описал Джон Постел в RFC 768 в 1980 году — документ занимает всего три страницы.[1] UDP появился, когда исходный монолитный протокол Серфа и Кана разделили на IP и TCP: стало ясно, что не всем приложениям нужна надёжная доставка, а некоторым — например, передаче речи — она даже вредит.

Устройство

Заголовок UDP занимает 8 байт и содержит четыре поля:

Поле Размер Назначение
Порт отправителя 2 байта куда отвечать (может быть нулевым)
Порт получателя 2 байта какой программе доставить
Длина 2 байта размер датаграммы с заголовком
Контрольная сумма 2 байта проверка целостности

Для сравнения: заголовок TCP — от 20 байт, плюс установление соединения, подтверждения и состояние на обеих сторонах. Каждая датаграмма UDP самостоятельна: границы сообщений сохраняются, в отличие от потока TCP.

UDP и TCP

UDP TCP
Соединение нет тройное рукопожатие
Доставка не гарантирована гарантирована, с повторами
Порядок не гарантирован гарантирован
Границы сообщений сохраняются поток байтов
Управление перегрузкой нет (ответственность приложения) встроено
Широковещание и мультикаст да нет
Задержка минимальная выше, особенно при потерях

Где используется

  • DNS — короткий запрос и ответ помещаются в одну датаграмму; при потере клиент просто повторит запрос.
  • DHCP — получение IP-адреса при подключении к сети, когда адреса ещё нет и соединение установить невозможно.
  • NTP — синхронизация времени.
  • Голос и видео — RTP поверх UDP: потерянный фрагмент лучше пропустить, чем ждать повтора и получить заикание.[3]
  • Онлайн-игры — актуальное положение игроков важнее устаревшего.
  • VPN — WireGuard и OpenVPN работают поверх UDP: внутренние TCP-соединения сами обеспечивают надёжность, а двойные повторы TCP-внутри-TCP только вредят.[5]
  • QUIC и HTTP/3 — современный веб-транспорт, реализующий надёжность, шифрование и управление перегрузкой поверх UDP.[4]
  • Мультикаст — рассылка одного потока многим получателям (IPTV, биржевые котировки).

Пример

import socket

# сервер
srv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
srv.bind(("0.0.0.0", 9999))
data, addr = srv.recvfrom(2048)          # ждём одну датаграмму
srv.sendto(b"pong", addr)

# клиент
cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
cli.settimeout(1.0)                       # ответа может и не быть
cli.sendto(b"ping", ("127.0.0.1", 9999))
print(cli.recvfrom(2048))

Нет ни listen, ни accept, ни connect: каждая датаграмма отправляется по адресу отдельно. Таймаут и повтор — забота приложения.

nc -u -l 9999                 # слушать UDP-порт
echo hello | nc -u host 9999  # отправить датаграмму
ss -ulnp                      # слушающие UDP-сокеты

Подводные камни

  • Размер датаграммы. Датаграмма больше MTU пути (обычно около 1500 байт для Ethernet) фрагментируется на уровне IP, а потеря любого фрагмента губит её целиком; многие сети фрагменты отбрасывают. Протоколы поверх UDP стараются укладываться примерно в 1200–1400 байт.
  • Ответственность приложения. Нужно самому решать, что делать с потерями, дубликатами и порядком, и не перегружать сеть: руководство RFC 8085 требует от протоколов поверх UDP собственного управления перегрузкой.[2]
  • NAT и файрволы. Без соединения промежуточные устройства держат состояние UDP-«потоков» недолго; приложения шлют периодические пакеты поддержки.
  • Атаки с усилением. Отправитель в UDP не проверяется, поэтому злоумышленник может подделать адрес жертвы и отправить маленький запрос к серверу, отвечающему большим ответом (открытые DNS-резолверы, NTP, memcached). Ответы обрушиваются на жертву — так устроены многие крупные DDoS-атаки.[6]

См. также

Источники

  1. RFC 768 — User Datagram Protocol
  2. RFC 8085 — UDP Usage Guidelines
  3. RFC 3550 — RTP: A Transport Protocol for Real-Time Applications
  4. RFC 9000 — QUIC: A UDP-Based Multiplexed and Secure Transport
  5. J. Donenfeld — WireGuard: Next Generation Kernel Network Tunnel
  6. Cloudflare Learning — UDP flood attack