Как TCP реализует / гарантирует передачу данных по порядку? - PullRequest
10 голосов
/ 30 марта 2012

Мне было интересно, как именно TCP реализует доставку по заказу.

Допустим, это список событий

  1. пакет1 отправлен, подтверждение получено.
  2. пакет2 отправлен, подтверждение не получено.
  3. отправлено 3 пакета.
  4. пакет4 отправлен.
  5. ack4 получено.
  6. ack3 получено.
  7. ack2 получено.

Можете ли вы описать мне, что именно происходит последовательно?

Ответы [ 2 ]

8 голосов
/ 30 марта 2012

Краткий ответ: каждый пакет содержит информацию о смещении (замаскированную под порядковым номером), указывающую, где в потоке находится его полезная нагрузка.

Допустим, произошло следующее: пакет 1 получен, пакет 2 не получен, а пакеты 3 и 4 получены. На этом этапе принимающий стек TCP знает, куда копировать содержимое пакетов 3 и 4 в буфер, и знает, что он до сих пор не получил предыдущие данные, поэтому он сделает данные пакета 1 доступными для чтения, но не сделает данные пакета 3 или 4 доступны до получения пакета 2.

Передача стека TCP обычно не ожидает подтверждений для какого-либо одного пакета перед отправкой следующего, но если он не получает подтверждения для данного пакета (а ACK могут и объединяются в один пакет для эффективности) , он будет передавать его до получения ACK.

Точная последовательность событий зависит от состояния сети, реализации стека TCP, выбранной политики TCP, параметров сокетов и других факторов.

4 голосов
/ 30 марта 2012

TCP-пакеты имеют порядковые номера (смещение байтов с момента запуска из памяти), и сообщения ACK подтверждают, что было получено конкретное смещение:

enter image description here

Таким образом, вы можете получить ситуацию, подобную:

data 1 (10 bytes)          ->
                           <- ack (10, data1)
data 2 (15 bytes)          ->
data 3 (10 bytes)          ->
data 4 ( 8 bytes)          ->
                           <- ack (25, data1/2/3)
                           <- ack (33, data1/2/3/4)

Другими словами, отправитель может продолжать отправку независимо от подтверждений до момента, когда его буферы заполнены (он должен хранить неподтвержденные пакеты на случай, если ему потребуется повторно передать их).

Это «разъединение» между отправкой и подтверждением может значительно ускорить поток данных.

На принимающей стороне пакеты могут поступать не по порядку и храниться до тех пор, пока что-то не будет доставлено на более высокие уровни по порядку.

Например, если data 3 прибыл до data 2, принимающая сторона будет удерживать его до прибытия data 2, тогда оба они будут отправлены вверх для доставки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...