Опишите механизм подтверждения и гарантии доставки данных в протоколе TCP.

Ответ

TCP (Transmission Control Protocol) — это протокол, ориентированный на соединение, который гарантирует надежную и упорядоченную доставку потока байт. Он достигает этого с помощью нескольких ключевых механизмов:

1. Номера последовательности (Sequence Numbers, Seq)

  • TCP рассматривает данные не как пакеты, а как непрерывный поток байт.
  • Каждому байту в потоке присваивается уникальный номер последовательности.
  • Когда отправитель посылает сегмент данных, он помечает его Seq номером, соответствующим первому байту в этом сегменте.

2. Подтверждения (Acknowledgements, Ack)

  • Когда получатель успешно принимает сегмент, он отправляет в ответ ACK-сегмент.
  • Номер Ack в этом ответном сегменте равен номеру Seq следующего байта, который получатель ожидает получить. Например, если был получен сегмент с Seq=100 и длиной 1000 байт, получатель отправит ACK=1100.
  • Это подтверждение является кумулятивным: ACK=1100 означает, что все байты с 0 до 1099 были успешно получены.

3. Таймауты и повторные передачи (Retransmission)

  • После отправки сегмента отправитель запускает таймер (Retransmission Timeout, RTO).
  • Если он не получает ACK для этого сегмента до истечения таймера, он считает сегмент утерянным и отправляет его повторно.
  • Время RTO вычисляется динамически на основе времени приема-передачи пакетов (Round-Trip Time, RTT).

Схема работы:

  1. Установка соединения (3-way handshake): Стороны обмениваются начальными номерами последовательности (ISN), чтобы синхронизировать Seq и Ack.
  2. Отправка данных:
    • Отправитель: Шлет сегмент с Seq=X.
    • Получатель: Принимает сегмент, отправляет ACK=X + length.
  3. Потеря пакета:
    • Отправитель: Шлет сегмент с Seq=Y, но он теряется.
    • Получатель: Ничего не получает и не отправляет ACK.
    • Отправитель: Таймер истекает, и он повторно отправляет сегмент с Seq=Y.

Дополнительные оптимизации:

  • SACK (Selective Acknowledgement): Позволяет получателю сообщить, какие именно сегменты он получил, даже если между ними есть пробелы. Это помогает отправителю повторно передавать только действительно утерянные сегменты, а не все подряд, что значительно повышает эффективность.