← Назад к вопросам

Что такое UDP протокол?

1.3 Junior🔥 161 комментариев
#Сетевые протоколы и API

Комментарии (1)

🐱
gpt-5-nanoPrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое UDP протокол?

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

Основные характеристики

  • Бессоединительный режим: каждая дата-그램 (сообщение) отправляется независимо.
  • Ненадежность: получатель может не получить сообщение, сообщение может придти в неверном порядке или дублироваться.
  • Небольшой оверхед: заголовок UDP занимает всего 8 байт.
  • Порядок и доставку обеспечивает приложение: любые требования к порядку и доставке должны реализовываться на уровне приложения.
  • Поддержка广播/мультимедиа: UDP удобен для приложений, которым важна скорость и локальные рассылки.
  • Поддержка ограничений MTU: полезная нагрузка UDP не должна превышать MTU сети, чтобы избежать фрагментации (fragmentation) на маршрутизаторах.

Структура заголовка UDP

  • Source Port: 16 бит
  • Destination Port: 16 бит
  • Length: 16 бит (включает заголовок UDP и данные)
  • Checksum: 16 бит (для IPv4 необязательно, для IPv6 обязательно)

Особенность: в IPv4 поле контрольной суммы UDP может иметь значение 0 (то есть не использоваться), в IPv6 контрольная сумма обязательно вычисляется. Контрольная сумма включает псевдозаголовок с IP-адресами, что помогает обнаружить ошибки.

Преимущества и ограничения

  • Преимущества:
    • очень низкая задержка;
    • простота реализации;
    • эффективен для скоростных и реального времени задач: голосовые/видео приложения, онлайн-игры, DNS-запросы и т. д.
  • Ограничения:
    • отсутствие обеспечения доставки, порядка и защиты от дубликатов;
    • риск фрагментации и связанных проблем;
    • требуется дополнительная логика в приложении для критичных задач.

Когда использовать UDP

  • Когда приоритет — минимальная задержка и большой объём однородных запросов (DNS, DHCP, реального времени 스트иминг, голосовые/видеоприложения, онлайн-игры).
  • Когда приложение может обрабатывать потерю пакетов или не требует строгой последовательности.
  • Когда нужна простота и масштабируемость без установления соединения.

Как работать с UDP в Go

Ниже пример простого UDP-сервера-эха и клинета. Обратите внимание на использование читающего цикла и отправку полученного обратно клиенту.

package main

import (
	"fmt"
	"net"
)

func main() {
	// Сервер: слушаем UDP на порту 12345
	addr := net.UDPAddr{Port: 12345, IP: net.IPv4zero}
	conn, err := net.ListenUDP("udp", &addr)
	if err != nil {
		fmt.Println("listen error:", err)
		return
	}
	defer conn.Close()

	buf := make([]byte, 1024)
	for {
		n, clientAddr, err := conn.ReadFromUDP(buf)
		if err != nil {
			fmt.Println("read error:", err)
			continue
		}
		fmt.Printf("recv %d bytes from %v: %s\n", n, clientAddr, string(buf[:n]))
		// Эхо-ответ
		_, err = conn.WriteToUDP(buf[:n], clientAddr)
		if err != nil {
			fmt.Println("write error:", err)
		}
	}
}
package main

import (
	"fmt"
	"net"
)

func main() {
	// Клиент: отправляем UDP-пакет к серверу
	raddr := net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 12345}
	conn, err := net.DialUDP("udp", nil, &raddr)
	if err != nil {
		fmt.Println("dial error:", err)
		return
	}
	defer conn.Close()

	msg := []byte("hello UDP")
	_, err = conn.Write(msg)
	if err != nil {
		fmt.Println("write error:", err)
		return
	}

	buf := make([]byte, 1024)
	n, err := conn.Read(buf)
	if err != nil {
		fmt.Println("read error:", err)
		return
	}
	fmt.Printf("echo: %s\n", string(buf[:n]))
}

Советы по реализации в продакшене:

  • держите полезную нагрузку в пределах MTU, чтобы избежать фрагментации;
  • рассматривайте применение DTLS или другого уровня защиты поверх UDP, если нужен конфиденциальность/аутентификация;
  • учитывайте NAT и возможные проблемы с пробросом портов;
  • реализуйте логику повторной передачи и контроль времени ожидания на стороне приложения там, где это критично.