MidТеория3 min

TCP vs UDP

Транспортные протоколы: трёхстороннее рукопожатие TCP, управление потоком и перегрузкой, UDP, QUIC и выбор протокола для System Design

Обзор транспортного уровня

Транспортный уровень (L4 в модели OSI) отвечает за доставку данных между приложениями на разных хостах. Два основных протокола -- TCP и UDP -- представляют фундаментальный компромисс между надёжностью и скоростью.

┌─────────────────────────────────────────────────┐
│             Application (HTTP, DNS)             │
├─────────────────────────────────────────────────┤
│         Transport (TCP / UDP / QUIC)            │
├─────────────────────────────────────────────────┤
│              Network (IP)                       │
├─────────────────────────────────────────────────┤
│         Data Link + Physical                    │
└─────────────────────────────────────────────────┘

Зачем это знать для System Design

  • Выбор TCP vs UDP определяет латентность и надёжность системы
  • Понимание congestion control помогает при проектировании real-time систем
  • QUIC меняет правила игры для HTTP/3 и современных приложений
  • На собеседовании часто спрашивают: «Почему вы выбрали TCP/UDP для этого компонента?»

TCP (Transmission Control Protocol)

Ключевые свойства

Свойство Описание
Надёжность Гарантированная доставка всех пакетов
Порядок Данные приходят в правильном порядке
Соединение Требуется установка соединения (handshake)
Flow control Отправитель не перегружает получателя
Congestion control Адаптация к пропускной способности сети
Full-duplex Одновременная передача в обе стороны

Структура TCP-сегмента

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│         Source Port (16)          │       Destination Port (16)    │
├───────────────────────────────────┼────────────────────────────────┤
│                    Sequence Number (32)                            │
├───────────────────────────────────────────────────────────────────┤
│                 Acknowledgment Number (32)                         │
├──────┬───────┬─┬─┬─┬─┬─┬─┬───────────────────────────────────────┤
│Offset│Reserv │U│A│P│R│S│F│           Window Size (16)             │
│ (4)  │ (3)   │R│C│S│S│Y│I│                                       │
│      │       │G│K│H│T│N│N│                                       │
├──────┴───────┴─┴─┴─┴─┴─┴─┼───────────────────────────────────────┤
│       Checksum (16)       │        Urgent Pointer (16)            │
├───────────────────────────┴───────────────────────────────────────┤
│                      Options (variable)                           │
├───────────────────────────────────────────────────────────────────┤
│                         Data                                      │
└───────────────────────────────────────────────────────────────────┘

Трёхстороннее рукопожатие (3-Way Handshake)

Установка TCP-соединения требует 3 пакетов -- 1 RTT (Round-Trip Time) до начала передачи данных.

Клиент                                  Сервер
  │                                       │
  │──── SYN (seq=x) ────────────────────►│
  │                                       │  Клиент хочет соединение
  │◄──── SYN-ACK (seq=y, ack=x+1) ──────│
  │                                       │  Сервер согласен
  │──── ACK (seq=x+1, ack=y+1) ────────►│
  │                                       │  Соединение установлено
  │◄═══════ Data Transfer ══════════════►│
  │                                       │

Закрытие соединения (4-Way Teardown):

Клиент                                  Сервер
  │──── FIN ────────────────────────────►│
  │◄──── ACK ────────────────────────────│
  │◄──── FIN ────────────────────────────│
  │──── ACK ────────────────────────────►│
  │                                       │
  │  (TIME_WAIT: 2*MSL ≈ 60 сек)        │

Для System Design: TIME_WAIT может стать проблемой при большом количестве короткоживущих соединений. Решения: connection pooling, SO_REUSEADDR, keep-alive.

Flow Control (Управление потоком)

TCP использует механизм скользящего окна (sliding window), чтобы отправитель не перегрузил получателя.

Получатель объявляет Window Size = 4 сегмента

Отправитель:  [1][2][3][4]  5  6  7  8  9  10
               ───────────
               Окно отправки (можно отправить без ACK)

После ACK на 1,2:
Отправитель:   1  2 [3][4][5][6]  7  8  9  10
                     ───────────
                     Окно сдвинулось вправо

Window Scaling: По умолчанию Window Size -- 16 бит (максимум 65535 байт). Опция Window Scale позволяет увеличить до 1 ГБ -- критично для высокоскоростных сетей.

Congestion Control (Управление перегрузкой)

TCP адаптирует скорость отправки к состоянию сети. Основные алгоритмы:

Slow Start + Congestion Avoidance

Congestion Window (cwnd)
    ^
    │         * * * * *    ← Congestion Avoidance
    │       *              (линейный рост)
    │     *
    │    *   ← ssthresh (порог)
    │   *
    │  *     ← Slow Start
    │ *      (экспоненциальный рост)
    │*
    └──────────────────────► Время
  1. Slow Start: cwnd начинается с 1 MSS, удваивается каждый RTT
  2. Congestion Avoidance: после ssthresh cwnd растёт на 1 MSS за RTT
  3. При потере пакета: ssthresh = cwnd/2, cwnd = 1 (TCP Tahoe) или cwnd = ssthresh (TCP Reno)

Современные алгоритмы

Алгоритм Подход Использование
CUBIC Кубическая функция роста cwnd Linux по умолчанию
BBR (Google) Оценка bandwidth и RTT Google, YouTube
BBR v2 Улучшенная fairness Новые системы
DCTCP ECN-aware для дата-центров Внутри дата-центров

Для System Design: BBR значительно улучшает throughput на каналах с высоким RTT и потерями. Google наблюдал рост пропускной способности на 2-25% после перехода на BBR.

TCP Fast Open (TFO)

Позволяет отправлять данные уже в SYN-пакете, экономя 1 RTT при повторных соединениях.

Первое соединение (получаем cookie):
  Клиент ── SYN ──────────────────────► Сервер
  Клиент ◄── SYN-ACK + Cookie ─────── Сервер
  Клиент ── ACK + Data ──────────────► Сервер

Последующие соединения (0-RTT):
  Клиент ── SYN + Cookie + Data ─────► Сервер   ← Данные сразу!
  Клиент ◄── SYN-ACK + Data ─────────  Сервер

UDP (User Datagram Protocol)

Ключевые свойства

Свойство Описание
Ненадёжность Нет гарантии доставки
Без порядка Пакеты могут прийти в любом порядке
Без соединения Нет handshake
Минимальный overhead Заголовок всего 8 байт
Быстрота Нет задержки на установку соединения
Broadcast/Multicast Поддержка групповой рассылки

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

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│         Source Port (16)          │       Destination Port (16)    │
├───────────────────────────────────┼────────────────────────────────┤
│          Length (16)              │          Checksum (16)         │
├───────────────────────────────────┴────────────────────────────────┤
│                           Data                                    │
└───────────────────────────────────────────────────────────────────┘

TCP заголовок: 20-60 байт   vs   UDP заголовок: 8 байт

Когда UDP лучше TCP

  • Потеря пакета допустима: видеозвонки, стриминг, онлайн-игры
  • Скорость важнее надёжности: DNS-запросы, NTP
  • Multicast нужен: IPTV, service discovery
  • Приложение реализует свою надёжность: QUIC, DTLS

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

Критерий TCP UDP
Соединение Да (3-way handshake) Нет
Надёжность Гарантированная доставка Best-effort
Порядок Гарантирован Не гарантирован
Overhead заголовка 20-60 байт 8 байт
Flow control Да Нет
Congestion control Да Нет
Скорость Ниже (из-за overhead) Выше
Broadcast Нет Да
Применение Web, API, email, файлы Видео, игры, DNS, IoT

QUIC

QUIC -- протокол транспортного уровня от Google, работающий поверх UDP. Стал основой HTTP/3.

Архитектура QUIC

┌─────────────────────────────────────────┐
│              HTTP/3                      │
├─────────────────────────────────────────┤
│         QUIC                            │
│  ┌────────┬────────┬────────────────┐   │
│  │ Stream │ Stream │  Connection    │   │
│  │ Mux    │ Ctrl   │  Migration     │   │
│  ├────────┴────────┤                │   │
│  │   TLS 1.3       │  0-RTT        │   │
│  │   (встроенный)  │  Resumption   │   │
│  ├─────────────────┴────────────────┤   │
│  │   Loss Detection + Recovery      │   │
│  │   Congestion Control             │   │
│  └──────────────────────────────────┘   │
├─────────────────────────────────────────┤
│              UDP                        │
├─────────────────────────────────────────┤
│              IP                         │
└─────────────────────────────────────────┘

Ключевые преимущества QUIC

1. Быстрое установление соединения:

TCP + TLS 1.3:    1 RTT (handshake) + 1 RTT (TLS) = 2 RTT
QUIC первое:      1 RTT (QUIC + TLS объединены)
QUIC повторное:   0 RTT (кешированные параметры)

2. Устранение Head-of-Line Blocking:

TCP: Потеря пакета в потоке A блокирует потоки B и C
     Stream A: [1][X][3]     ← пакет 2 потерян
     Stream B: [1][2][3]     ← ЗАБЛОКИРОВАН (ждёт A)
     Stream C: [1][2]        ← ЗАБЛОКИРОВАН

QUIC: Потоки независимы
     Stream A: [1][X][3]     ← ждёт только A
     Stream B: [1][2][3]     ← доставлено ✓
     Stream C: [1][2]        ← доставлено ✓

3. Connection Migration: При смене Wi-Fi на LTE TCP-соединение разрывается (смена IP). QUIC использует Connection ID и продолжает работу.

Выбор протокола в System Design

Дерево решений

Нужна гарантированная доставка?
├── ДА → Критична низкая латентность?
│   ├── ДА → QUIC / HTTP/3
│   └── НЕТ → TCP / HTTP/1.1-2
└── НЕТ → Допустимы потери данных?
    ├── ДА → UDP (видео, аудио, игры)
    └── НЕТ → Надёжность поверх UDP (QUIC, custom protocol)

Примеры из реального мира

Система Протокол Причина
Web API (REST/GraphQL) TCP (HTTP) Надёжность, стандартность
Видеозвонки (Zoom) UDP + SRTP Низкая латентность, потеря кадра ОК
Онлайн-игры UDP + custom Позиция игрока нужна сейчас, а не через RTT
DNS-запросы UDP (порт 53) Маленький запрос, быстрый ответ
DNS over HTTPS TCP (HTTPS) Приватность важнее скорости
YouTube стриминг QUIC (HTTP/3) Мультиплексирование, 0-RTT
Базы данных TCP Надёжность транзакций
IoT телеметрия UDP / MQTT Экономия ресурсов
Микросервисы (gRPC) TCP (HTTP/2) Стриминг, надёжность

Важные числа для собеседования

Метрика Значение
TCP handshake 1 RTT (~1-100 мс в зависимости от расстояния)
TLS 1.3 handshake 1 RTT
QUIC handshake (первое) 1 RTT
QUIC handshake (повторное) 0 RTT
TCP заголовок 20-60 байт
UDP заголовок 8 байт
MSS (Max Segment Size) 1460 байт (при MTU 1500)
Начальный cwnd 10 MSS (~14.6 KB)

Проверь себя

Какой алгоритм управления перегрузкой используется в Linux по умолчанию?

Что такое Head-of-Line Blocking в TCP и как QUIC решает эту проблему?

Почему для видеозвонков обычно выбирают UDP, а не TCP?

Какой размер заголовка у UDP-датаграммы?

Сколько RTT требуется для установления TCP-соединения (3-way handshake)?