TCP: надёжная доставка и порядок
TCP: надёжная доставка и порядок
В предыдущем уроке мы поместили TCP на транспортный уровень стека. Теперь разберёмся, что именно он делает. Интернет-протокол (IP) доставляет пакеты, но не гарантирует ни доставку, ни порядок. Пакет может потеряться, прийти с опозданием или продублироваться. TCP (Transmission Control Protocol) решает все эти проблемы, превращая ненадёжный IP-канал в надёжное соединение.
Зачем нужен TCP поверх IP
IP — это как отправка открыток: ты бросаешь их в почтовый ящик, но понятия не имеешь, дойдут ли они, в каком порядке и не потеряется ли часть. TCP добавляет к этому:
- Гарантию доставки. Если пакет потерялся — отправитель узнает и перешлёт.
- Порядок. Пакеты собираются в правильной последовательности, даже если пришли вразнобой.
- Контроль перегрузки. TCP не заваливает сеть пакетами быстрее, чем она может переварить.
- Управление потоком. Быстрый отправитель не перегружает медленного получателя.
Веб-страницы, загрузка файлов, электронная почта — всё, что требует «все данные, без ошибок, в правильном порядке» — использует TCP.
Порядковые номера: как TCP наводит порядок
TCP нумерует каждый отправленный байт. Когда ты передаёшь файл размером 1000 байт, TCP разбивает его на сегменты и присваивает каждому байту порядковый номер (sequence number):
Сегмент 1: байты 1–500
Сегмент 2: байты 501–1000
Получатель отправляет подтверждение (acknowledgment, ACK) с номером следующего ожидаемого байта. Например, ACK 501 означает: «я получил байты 1–500, жду байт 501».
Если сегмент 2 (501–1000) придёт раньше сегмента 1, получатель не отдаст данные приложению — он подождёт сегмент 1 и соберёт всё по порядку.
Подтверждения и повторная отправка
Отправитель запускает таймер для каждого отправленного сегмента. Если за отведённое время (обычно рассчитывается динамически на основе текущих задержек) ACK не приходит — сегмент отправляется заново.
Это похоже на разговор с плохой связью: «Ты меня слышишь? Приём». Если собеседник молчит дольше обычного — ты повторяешь фразу.
Ключевой момент: TCP пересылает только потерянные сегменты, а не весь файл заново. Если из 1000 сегментов потерялся один — пересылается только он.
Sliding window: не ждать ACK на каждый сегмент
Было бы глупо отправлять сегмент и ждать подтверждения перед отправкой следующего — пропускная способность канала использовалась бы впустую. Вместо этого TCP использует скользящее окно (sliding window) — количество байт, которое отправитель может послать, не дожидаясь подтверждения:
Отправитель может отправить до 4 сегментов без ACK:
[Отправлено: 1] [2] [3] [4] [Готово: 5] [6] [7] [8] ...
↑ уже ACK ↑ отправлены, ждут ACK ↑ ещё не отправлены
└── окно сдвигается при получении ACK ──→
Размер окна подстраивается динамически: если сеть быстрая и без потерь — окно растёт. Если пошли потери — TCP уменьшает окно и замедляется. Это называется контроль перегрузки (congestion control).
Накопительные подтверждения
TCP использует накопительные (cumulative) подтверждения. ACK 2001 означает: «все байты до 2001 получены». Если отправитель получает ACK 2001 после трёх одинаковых ACK 1001, он делает вывод: сегмент с байтами 1001–1500 потерян, и пересылает его. Этот механизм называется fast retransmit.
Управление потоком: чтобы получатель не захлебнулся
Получатель в каждом ACK сообщает размер своего окна приёма (receive window) — сколько байт он готов принять прямо сейчас. Если приложение на приёмной стороне медленно читает данные, окно уменьшается, и отправитель снижает темп. Это защищает медленные устройства от переполнения буфера.
TCP vs «голый» IP
Сведём разницу в таблицу:
| Характеристика | IP (без TCP) | TCP поверх IP |
|---|---|---|
| Доставка | Не гарантирована | Гарантирована (повтор) |
| Порядок | Не гарантирован | Гарантирован (seq номера) |
| Дубликаты | Возможны | Отфильтровываются |
| Контроль скорости | Нет | Да (congestion control) |
| Соединение | Без установки | Требует установки |
Проверь себя
- Что означает ACK 3001 в ответ на сегменты TCP?
- Зачем TCP нумерует байты, а не сегменты?
- Что произойдёт, если отправитель перестанет получать подтверждения?
- Получатель подтверждает получение всех байтов до номера 3001 (не включая его). Следующий ожидаемый байт — 3001.
- Потому что сегменты могут быть разного размера и фрагментироваться. Нумерация байтов даёт точную и однозначную систему: всегда понятно, какие именно данные подтверждены.
- Отправитель будет повторно слать неподтверждённые сегменты с увеличивающимся интервалом. После нескольких неудачных попыток (обычно 5–10) TCP объявит соединение разорванным.
Что унести с урока
- TCP превращает ненадёжный IP в надёжную передачу: он гарантирует доставку и порядок.
- Порядковые номера (sequence numbers) и подтверждения (ACK) — основа надёжности.
- Sliding window позволяет отправлять несколько сегментов без ожидания ACK.
- Контроль перегрузки адаптирует скорость к состоянию сети.
- Управление потоком защищает медленного получателя от быстрого отправителя.
Мы сказали, что TCP требует установки соединения перед передачей данных. Как именно это происходит? В следующем уроке разберём трёхстороннее рукопожатие TCP — классический танец из трёх шагов, с которого начинается любое TCP-соединение.