Перейти к основному содержимому

TCP — соединение, окно и перегрузка

Разработчику

Зачем отдельная статья про TCP

В обзоре протоколов TCP уже сравнивают с UDP. Здесь — механизмы, которые делают HTTP и SSH предсказуемыми: установление соединения, повтор при потерях, согласование скорости с каналом и с соседними потоками. Эти идеи повторяются в QUIC и в разборе «медленного интернета» — 612.


Соединение и сокет

TCP даёт приложению поток байтов между двумя конечными точками. На транспортном уровне пара IP-адрес + порт на каждой стороне называется сокетом. Полный идентификатор сессии — четвёрка (клиент IP:порт, сервер IP:порт).

Перед передачей данных стороны проходят трёхстороннее рукопожатие (three-way handshake):

ШагНаправлениеФлагиСмысл
1Клиент → серверSYN«Хочу соединение», начальный номер последовательности
2Сервер → клиентSYN, ACK«Принял, вот мой номер»
3Клиент → серверACK«Подтверждаю, можно слать данные»

После шага 3 соединение в состоянии ESTABLISHED. Закрытие — обмен сегментами с FIN и ACK (часто четыре пакета). Подробный разбор в контексте HTTPS — шаг 2 загрузки сайта.

Полуоткрытые соединения

Сервер хранит таблицу соединений, ожидающих завершения рукопожатия. Массовая атака SYN-flood заполняет эту таблицу — см. загрузку сайта и DDoS.


Сегмент TCP и номера последовательности

Данные приложения режутся на сегменты. В заголовке TCP важны:

  • Порты источника и назначения (мультиплексирование процессов на одном IP);
  • Номер последовательности — позиция первого байта сегмента в потоке;
  • Номер подтверждения (ACK) — следующий ожидаемый байт от другой стороны;
  • Флаги SYN, ACK, FIN, RST, PSH;
  • Размер окна приёма — сколько байт получатель готов принять без подтверждения.

Каждый принятый сегмент обычно подтверждается ACK. При потере сегмента отправитель по таймауту или дублирующему ACK пересылает данные.


RTT и таймаут

RTT (Round-Trip Time) — время туда-обратно до узла, который отвечает. TCP оценивает RTT по подтверждениям и выставляет таймаут повторной передачи чуть больше среднего RTT (сглаживание колебаний).

Длинный RTT (спутник, другой континент) увеличивает время до первого байта ответа и замедляет рост скорости при slow start. Поэтому для интерактивных сервисов важна география — CDN.


Управление потоком (flow control)

Получатель объявляет окно приёма (receive window): «столько байт могу буферизовать сейчас». Отправитель не засылает больше, чем разрешено. Это защищает медленный клиент от переполнения памяти быстрым сервером.

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


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

Перегрузка — когда суммарный входящий трафик на узле или линии превышает скорость исходящего канала. Растут очереди, задержка и потери — см. формулу задержки.

TCP каждый отправитель ведёт окно перегрузки (congestion window, cwnd) — лимит данных «в полёте» без подтверждения. Алгоритм меняет cwnd, чтобы:

  • быстро найти доступную полосу на новом соединении;
  • отступить при признаках перегрузки (потеря, явное уведомление).

Типичная схема (TCP Reno и близкие реализации в Linux/Windows):

ФазаПоведение cwnd
Slow startПосле установления соединения cwnd мал; при каждом успешном RTT cwnd удваивается, пока не дойдёт до порога или пока не появятся потери
Предотвращение перегрузкиРост линейный (примерно +1 MSS на RTT)
При потереcwnd резко уменьшают (multiplicative decrease), затем снова осторожный рост

Именно slow start объясняет, почему короткая загрузка множества мелких файлов на странице не выходит на полный тариф 100 Мбит/с, а долгая закачка — выходит через десятки секунд — разбор в 612.

BDP (bandwidth-delay product) — произведение пропускной способности на RTT: сколько байт должно «лежать в проводе», чтобы канал был заполнен. Если cwnd меньше BDP, линия недогружена.

TCP поверх TCP

VPN в режиме TCP-туннеля поверх TCP в интернете даёт два независимых регулятора перегрузки — при потерях скорость падает сильнее. Предпочтительнее UDP-туннели (WireGuard, QUIC) — VPN.


Мультиплексирование на одном IP

На одном хосте десятки вкладок браузера — это разные порты и отдельные TCP-соединения с одним и тем же IP сервера (часто 443). ОС по паре портов направляет сегменты нужному сокету процесса. Обзор портов — 618.

HTTP/2 мультиплексирует запросы в одном TCP-соединении; HTTP/3 переносит потоки в QUIC поверх UDP — дополнительные технологии.


Связь с практикой

СимптомВозможная причина на уровне TCP
Сайт долго «думает» до первого байтаВысокий RTT, очередь DNS, медленное рукопожатие + TLS
Скорость скачивания растёт по секундамSlow start, ограничение cwnd
Скорость падает вечеромПотери и перегрузка у провайдера, уменьшение cwnd
Всё обрываетсяRST, таймаут, фаервол режет соединение

Диагностика: вкладка «Сеть» в DevTools, curl -w time_connect, ss -ti на Linux, захват в Wireshark — 615.


Дальше по курсу

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").