Есть ли у TCP и UDP операция подтверждения доставки
Что проверяют
Понимаете ли вы, что именно подтверждает TCP и чего он не гарантирует приложению. Ответ «у TCP есть, у UDP нет» интервьюер ждёт, но оценивает следующий слой. Следом обычно спрашивают, означает ли успешный conn.Write в Go, что сервер получил данные.
Как отвечать
У TCP подтверждения встроены в протокол:
- ACK по номерам последовательности: каждый байт потока пронумерован, получатель сообщает, до какого байта всё дошло. Подтверждения накопительные, опция SACK позволяет сообщить о кусках, полученных после дыры;
- повторная передача: по таймауту (RTO) или быстрее, после трёх дублирующихся ACK;
- управление потоком и перегрузкой: окно получателя не даёт завалить медленного клиента, окно перегрузки (CUBIC в Linux по умолчанию, BBR как альтернатива) не даёт завалить сеть.
Ключевой нюанс: ACK подтверждает, что байты попали в буфер ядра на той стороне, а не что приложение их прочитало и обработало. В Go conn.Write без ошибки значит лишь, что данные скопированы в буфер отправки. Если процесс на сервере упал сразу после получения, данные потеряны, хотя ACK уже ушёл. Поэтому надёжные протоколы делают свои подтверждения на уровне приложения: ответ на запрос, ack в брокере сообщений.
У UDP подтверждений нет: датаграмма может потеряться, прийти дважды или не по порядку, и отправитель об этом не узнает. Зато сохраняются границы сообщений и нет установки соединения. Надёжность при необходимости строят поверх: QUIC (основа HTTP/3) реализует свои ACK и повторы, DNS просто повторяет запрос по таймауту. В Go это net.ListenPacket("udp", addr) и ReadFrom/WriteTo, для QUIC обычно берут quic-go.
Где спотыкаются
Говорят, что ACK означает «сервер обработал». Это подтверждение транспортного уровня, приложение могло упасть сразу после.
Забывают, что TCP это поток байтов без границ сообщений. Один Write может прийти несколькими Read, поэтому нужен фрейминг: префикс длины или разделитель.
Называют UDP «быстрым, но всё теряющим». Потери зависят от сети, а выбор UDP оправдан там, где опоздавший пакет бесполезен: голос, игры, телеметрия.