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

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

2.3 Middle🔥 111 комментариев
#DevOps и инфраструктура

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

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

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

UDP протокол (User Datagram Protocol)

UDP — это протокол транспортного уровня (Layer 4) в модели OSI, предназначенный для быстрой передачи данных без гарантии доставки. В отличие от TCP, UDP работает без установления соединения.

Ключевые характеристики

Без соединения (connectionless) — не требует установки соединения перед отправкой данных. Клиент сразу отправляет пакеты (датаграммы) серверу.

Отсутствие гарантий — UDP не гарантирует:

  • Доставку пакета (пакет может быть потерян)
  • Порядок доставки (пакеты могут прийти в другом порядке)
  • Отсутствие дубликатов (пакет может прийти несколько раз)

Низкая задержка (low latency) — минимальные накладные расходы делают UDP быстрым. Идеален для приложений реального времени.

Меньший размер заголовка — 8 байт против 20+ байт у TCP.

Сравнение TCP vs UDP

ХарактеристикаTCPUDP
СоединениеС установкойБез соединения
Гарантия доставкиДаНет
Порядок пакетовГарантированНе гарантирован
СкоростьМедленнееБыстрее
ИспользованиеФайлы, сообщенияВидео, игры, DNS
Заголовок20+ байт8 байт

Структура UDP датаграммы

0      7 8     15 16    23 24    31
+--------+--------+--------+--------+
|     Source Port     | Destination Port |
+--------+--------+--------+--------+
|           Length            |    Checksum      |
+--------+--------+--------+--------+
|                                              |
|               Data                           |
|                                              |
+--------+--------+--------+--------+

Каждая датаграмма содержит: порт источника, порт назначения, длину и контрольную сумму.

Применение UDP в Python

Создание UDP сервера:

import socket

# Создаём UDP сокет
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('localhost', 5005))

print('UDP сервер слушает на порту 5005')

while True:
    # Получаем данные
    data, address = server_socket.recvfrom(1024)
    print(f'Получено от {address}: {data.decode()}')
    
    # Отправляем ответ
    server_socket.sendto(b'Сообщение получено', address)

Создание UDP клиента:

import socket

client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Отправляем данные
client_socket.sendto(b'Hello, UDP!', ('localhost', 5005))

# Получаем ответ
data, address = client_socket.recvfrom(1024)
print(f'Ответ: {data.decode()}')

client_socket.close()

Реальные примеры использования UDP

DNS — запросы DNS используют UDP для быстрого разрешения доменов:

import socket

# DNS запрос (упрощённо)
dns_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
dns_socket.sendto(dns_query, ('8.8.8.8', 53))
response, _ = dns_socket.recvfrom(512)

Онлайн видео/потоки — потоковое видео (YouTube, Twitch) часто использует UDP для низкой задержки.

Онлайн игры — многопользовательские игры требуют минимальной задержки, поэтому используют UDP с собственным механизмом надёжности.

VoIP — голосовые вызовы (Skype, Zoom) используют UDP для минимальной задержки.

NTP (Network Time Protocol) — синхронизация времени требует минимальных накладных расходов.

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

Подходит для:

  • Потоков, где приемлема потеря данных
  • Приложений реального времени (видео, игры, VoIP)
  • Малого объёма данных
  • Broadcast/multicast сообщений

НЕ подходит для:

  • Критичных данных (платежи, финансы)
  • Приложений, требующих гарантии доставки
  • Больших файлов

Надёжность в UDP

Если требуется надёжность, разработчик реализует механизм на уровне приложения:

import time
import json

class ReliableUDP:
    def __init__(self, socket_obj):
        self.socket = socket_obj
        self.seq_num = 0
        self.acks = {}
    
    def send_with_ack(self, data, address, timeout=2):
        message = {
            'seq': self.seq_num,
            'data': data
        }
        
        start = time.time()
        while time.time() - start < timeout:
            self.socket.sendto(json.dumps(message).encode(), address)
            try:
                self.socket.settimeout(0.5)
                response, _ = self.socket.recvfrom(1024)
                if response.decode() == f'ACK:{self.seq_num}':
                    self.seq_num += 1
                    return True
            except socket.timeout:
                continue
        
        return False  # Не получили подтверждение

UDP — мощный инструмент для специфичных задач. Выбор между TCP и UDP зависит от требований приложения к надёжности и скорости.

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