# TCP

> Протокол управления передачей — транспортный протокол интернета, обеспечивающий надёжную упорядоченную доставку потока байтов между программами с управлением потоком и перегрузкой.

Источник: https://llmdocs.ru/wiki/tcp/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Полное название**: Transmission Control Protocol
- **Авторы**: Винтон Серф, Роберт Кан
- **Спецификация**: RFC 793 (1981), актуальная — RFC 9293 (2022)
- **Уровень**: транспортный (модели OSI и TCP/IP)
- **Гарантии**: надёжность, порядок, целостность, управление потоком и перегрузкой
- **Установление соединения**: тройное рукопожатие (SYN, SYN-ACK, ACK)
- **Алгоритмы перегрузки**: Reno, CUBIC (по умолчанию в Linux), BBR
**TCP** (англ. *Transmission Control Protocol* — протокол управления передачей) — транспортный протокол стека [TCP/IP](https://llmdocs.ru/wiki/tcp-ip.md), который превращает ненадёжную доставку пакетов протоколом IP в надёжный упорядоченный поток байтов между двумя программами. TCP гарантирует, что данные дойдут полностью, без искажений и в том порядке, в каком были отправлены, а скорость передачи подстроится под возможности получателя и сети.

Поверх TCP работают [HTTP](https://llmdocs.ru/wiki/http.md)/1.1 и HTTP/2, [TLS](https://llmdocs.ru/wiki/tls.md), [SSH](https://llmdocs.ru/wiki/ssh.md), почтовые протоколы, протоколы баз данных — большая часть трафика интернета. Альтернатива для задач, где важнее скорость, чем гарантии, — [UDP](https://llmdocs.ru/wiki/udp.md).

## История

Винтон Серф и Роберт Кан описали протокол в 1974 году; позже его разделили на IP (маршрутизация) и TCP (надёжная доставка). Спецификация вышла как RFC 793 в 1981 году, а в 2022 году её переработали и объединили с последующими исправлениями в RFC 9293.[1] В 1986 году интернет пережил серию «коллапсов перегрузки», когда полезная пропускная способность падала в тысячу раз; Ван Якобсон в 1988 году предложил алгоритмы управления перегрузкой, которые спасли сеть и с изменениями используются до сих пор.[2]

## Установление и завершение соединения

TCP — протокол **с установлением соединения**. Перед передачей данных стороны обмениваются тремя сегментами — **тройное рукопожатие**:

```text
Клиент                         Сервер
  | ------ SYN (seq=x) ---------> |
  | <---- SYN-ACK (seq=y, ack=x+1) |
  | ------ ACK (ack=y+1) -------> |
  |      соединение установлено    |
```

Рукопожатие занимает один круг «туда-обратно» (RTT) до отправки первых данных, а TLS поверх TCP добавляет ещё один круг. Завершение — обмен сегментами FIN и ACK с каждой стороны; сторона, закрывшая соединение первой, проводит некоторое время в состоянии **TIME_WAIT**, чтобы опоздавшие пакеты не попали в новое соединение. Сегмент **RST** обрывает соединение немедленно — например, при попытке подключиться к закрытому порту.

## Надёжность и порядок

- **Номера последовательности.** Каждый байт потока имеет номер; получатель собирает данные по порядку, даже если пакеты пришли вразнобой, и отбрасывает дубликаты.
- **Подтверждения.** Получатель сообщает, до какого байта всё получено (ACK). Неподтверждённые данные отправитель повторяет по таймауту или после трёх повторных подтверждений (*fast retransmit*).
- **Контрольная сумма** выявляет повреждённые сегменты.

## Управление потоком и перегрузкой

**Управление потоком** защищает получателя: в каждом подтверждении он сообщает размер **окна** — сколько ещё байтов готов принять. Медленный получатель автоматически притормаживает быстрого отправителя.

**Управление перегрузкой** защищает сеть. Отправитель держит *окно перегрузки* и увеличивает его, пока сеть справляется: сначала экспоненциально (**медленный старт**), затем линейно. Потеря пакета воспринимается как сигнал перегрузки, и окно резко уменьшается. Алгоритмы:

| Алгоритм | Сигнал | Где используется |
|---|---|---|
| Reno, NewReno | потери пакетов | классика, учебники |
| CUBIC | потери; рост окна по кубической функции времени | по умолчанию в Linux, Windows, macOS[3] |
| BBR | оценка пропускной способности и минимальной задержки | Google, YouTube; полезен на каналах с потерями[4] |

```bash
sysctl net.ipv4.tcp_congestion_control                # текущий алгоритм в Linux
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr    # включить BBR
```

## Порты и сокеты

Соединение однозначно определяется четвёркой: IP-адрес и порт клиента, IP-адрес и порт сервера. Сервер слушает известный порт (443 для HTTPS, 22 для SSH, 5432 для PostgreSQL), а клиент получает случайный временный порт.

```bash
ss -tlnp                   # слушающие TCP-сокеты и процессы
ss -tn state established   # установленные соединения
ss -s                      # сводка, включая TIME_WAIT
nc -vz example.com 443     # проверить, открыт ли порт
```

Утилита `ss` — современная замена `netstat`.[6]

## Проблемы и оптимизации

- **Блокировка начала очереди** (*head-of-line blocking*). Поток строго упорядочен: потеря одного пакета задерживает все последующие данные, даже относящиеся к другим запросам. В HTTP/2 это тормозит все параллельные потоки — главная причина появления [QUIC](https://llmdocs.ru/wiki/quic.md).
- **Задержка установления.** Рукопожатие TCP плюс TLS — два круга до первого байта данных. TCP Fast Open позволяет отправлять данные уже в SYN при повторных соединениях,[5] TLS 1.3 сокращает своё рукопожатие до одного круга.
- **Алгоритм Нейгла** склеивает мелкие записи в один сегмент, экономя трафик, но добавляя задержку; интерактивные приложения отключают его опцией `TCP_NODELAY`.
- **Keepalive.** Простаивающие соединения могут обрываться промежуточными устройствами (NAT, файрволы); периодические проверки поддерживают их и выявляют «мёртвые» соединения.

## TCP и приложения

Для программиста TCP — это сокет, в который пишут и из которого читают поток байтов. Важно помнить, что это **поток, а не сообщения**: один вызов `send` не обязательно соответствует одному `recv` на другой стороне. Протокол приложения должен сам разделять сообщения — длиной в заголовке, разделителями или, как в HTTP, заголовком `Content-Length`.

## См. также

- [UDP](https://llmdocs.ru/wiki/udp.md)
- [QUIC](https://llmdocs.ru/wiki/quic.md)
- [TCP/IP](https://llmdocs.ru/wiki/tcp-ip.md)
- [Модель OSI](https://llmdocs.ru/wiki/osi-model.md)
- [HTTP/2 и HTTP/3](https://llmdocs.ru/wiki/http2-http3.md)

## Источники

1. [RFC 9293 — Transmission Control Protocol (TCP)](https://www.rfc-editor.org/rfc/rfc9293)
2. [V. Jacobson — Congestion Avoidance and Control (SIGCOMM 1988)](https://dl.acm.org/doi/10.1145/52324.52356)
3. [RFC 9438 — CUBIC for Fast and Long-Distance Networks](https://www.rfc-editor.org/rfc/rfc9438)
4. [N. Cardwell et al. — BBR: Congestion-Based Congestion Control (ACM Queue, 2016)](https://queue.acm.org/detail.cfm?id=3022184)
5. [RFC 7413 — TCP Fast Open](https://www.rfc-editor.org/rfc/rfc7413)
6. [ss(8) — Linux manual page](https://man7.org/linux/man-pages/man8/ss.8.html)
