Что такое трёхстороннее рукопожатие (three-way handshake)?
Three-way handshake — процедура установления TCP-соединения между клиентом и сервером, состоящая из обмена тремя сегментами (SYN → SYN-ACK → ACK), в ходе которого обе стороны согласовывают начальные номера последовательностей и подтверждают готовность к передаче данных.
Аналогия из жизни: это как телефонный звонок. Вы звоните и говорите «Алло?» (SYN). Собеседник отвечает «Алло, слышу вас!» (SYN-ACK). Вы подтверждаете «Отлично, и я вас слышу, давайте поговорим» (ACK). Только после этого начинается разговор.
Схема установления соединения
Пример
Клиент Сервер
| |
|-------- SYN (seq=x) ------------>| 1. Клиент хочет соединиться
| Состояние: SYN_SENT | Состояние: LISTEN
| |
|<--- SYN-ACK (seq=y, ack=x+1) ---| 2. Сервер подтверждает и предлагает свой номер
| Состояние: SYN_SENT | Состояние: SYN_RECEIVED
| |
|-------- ACK (ack=y+1) ---------->| 3. Клиент подтверждает
| Состояние: ESTABLISHED | Состояние: ESTABLISHED
| |
| Соединение установлено |
Детальное описание шагов
Шаг 1 — SYN (Synchronize):
- Клиент отправляет сегмент с флагом SYN и начальным номером последовательности (
seq=x, где x — случайное число, ISN — Initial Sequence Number) - Клиент переходит в состояние
SYN_SENT - ISN генерируется случайно для защиты от атак подмены (TCP sequence prediction)
Шаг 2 — SYN-ACK:
- Сервер получает SYN, отвечает сегментом с флагами SYN и ACK
seq=y(свой начальный номер),ack=x+1(подтверждает получение SYN клиента)- Сервер переходит в состояние
SYN_RECEIVED
Шаг 3 — ACK:
- Клиент отправляет ACK с
ack=y+1(подтверждает получение SYN сервера) - Оба переходят в состояние
ESTABLISHED— соединение установлено, можно передавать данные - Начиная с этого сегмента, клиент уже может отправлять данные
Зачем три шага, а не два?
- Оба участника должны согласовать начальные номера последовательностей (ISN) для каждого направления — это требует по одному сообщению в каждую сторону плюс подтверждение
- Два шага не гарантируют, что обе стороны готовы к передаче данных
- Защита от дублированных SYN-пакетов от прошлых соединений (stale segments)
Завершение TCP-соединения (four-way handshake)
Пример
Клиент Сервер
|-------- FIN ------------------>| 1. Клиент хочет завершить (FIN_WAIT_1)
|<-------- ACK -----------------| 2. Сервер подтверждает (CLOSE_WAIT)
| | Клиент: FIN_WAIT_2
|<-------- FIN -----------------| 3. Сервер тоже завершает (LAST_ACK)
|-------- ACK ------------------>| 4. Клиент подтверждает (TIME_WAIT)
| | Сервер: CLOSED
| (ждёт 2×MSL ≈ 60 с) |
| Состояние: CLOSED |
Состояния TCP-соединения
| Состояние | Описание |
|---|---|
LISTEN |
Сервер ожидает входящих соединений |
SYN_SENT |
Клиент отправил SYN, ожидает SYN-ACK |
SYN_RECEIVED |
Сервер получил SYN, отправил SYN-ACK |
ESTABLISHED |
Соединение установлено, передача данных |
FIN_WAIT_1 |
Отправлен FIN, ожидание ACK |
FIN_WAIT_2 |
Получен ACK на FIN, ожидание FIN от другой стороны |
CLOSE_WAIT |
Получен FIN, ожидание закрытия от приложения |
TIME_WAIT |
Ожидание гарантии доставки последнего ACK (2×MSL) |
CLOSED |
Соединение закрыто |
Для Java-разработчика
new Socket("host", port)— внутри происходит three-way handshakesocket.close()— инициирует four-way handshake- При большом количестве короткоживущих соединений состояния
TIME_WAITмогут исчерпать ресурсы (порты, файловые дескрипторы). Решение: HTTP keep-alive, connection pooling (HikariCP для JDBC) ServerSocketс параметромbacklogуправляет очередью входящих соединений в состоянии SYN_RECEIVED
Вывод
Three-way handshake — обязательный этап установления каждого TCP-соединения. Он гарантирует, что обе стороны готовы к обмену данными и согласовали параметры. Завершение соединения — четырёхэтапное, потому что каждая сторона может иметь данные для отправки.
На собеседовании: уверенно нарисуйте диаграмму SYN → SYN-ACK → ACK. Часто спрашивают, зачем нужен
TIME_WAIT(чтобы последний ACK гарантированно дошёл и чтобы stale-пакеты от старого соединения не попали в новое). Также стоит упомянуть SYN flood-атаку — злоумышленник отправляет множество SYN, не завершая handshake, и исчерпывает ресурсы сервера (защита — SYN cookies).