Выбрать главу

Если последний сегмент ACK теряется (илл. 6.14 (б)), ситуацию спасает таймер. Когда время истекает, соединение разрывается в любом случае.

Теперь рассмотрим случай потери второго DR. Пользователь, инициировавший разъединение, не получит ожидаемого ответа, у него истечет время ожидания, и он начнет все сначала. На илл. 6.14 (в) показано, как это происходит, если все последующие запросы и подтверждения успешно доходят до адресатов.

Последний сценарий (илл. 6.14 (г)) аналогичен предыдущему с одной лишь разницей: в этом случае предполагается, что все повторные попытки передать DR также терпят неудачу, поскольку все сегменты теряются. После N попыток отправитель, наконец, сдается и разрывает соединение. Тем временем у получателя также истекает время, и он тоже отсоединяется.

Хотя такого протокола обычно бывает вполне достаточно, теоретически он может ошибиться, если потеряются изначальный DR и все N повторных передач. Отправитель сдается и разрывает соединение, тогда как другая сторона ничего не знает о попытках разорвать связь и сохраняет активность. В результате получается полуоткрытое соединение, что недопустимо.

Этой ситуации можно избежать, если не позволить отправителю сдаваться после N повторных передач, а заставить его продолжать попытки, пока не будет получен ответ. Однако если другой стороне будет разрешено разрывать связь по таймеру, тогда отправитель действительно будет вечно повторять попытки, так как ответа он не получит никогда. Если же получателю также не разрешать разрывать соединение по таймеру, то протокол зависнет в ситуации, изображенной на илл. 6.14 (г).

Илл. 6.14. Четыре сценария разрыва соединения. (а) Нормальный случай «тройного рукопожатия». (б) Потеряно последнее подтверждение. (в) Потерян ответ. (г) Потерян ответ и последующие запросы разъединения

Чтобы избавиться от полуоткрытых соединений, используется правило, гласящее, что если по соединению в течение определенного времени не приходит ни одного сегмента, оно автоматически разрывается. Таким образом, если одна сторона разорвет соединение, другая обнаружит отсутствие активности и также отсоединится. Правило работает и в тех случаях, когда соединение разрывается не по инициативе одной из сторон, а по причине невозможности передачи пакетов между этими хостами в сети.

Для реализации этого правила каждая сторона должна иметь таймер, который перезапускается после отправки каждого сегмента. Если таймер срабатывает, передается пустой сегмент — чтобы другая сторона не отсоединилась. Но если применяется правило автоматического разъединения и передается слишком много пустых сегментов подряд, только чтобы линия не простаивала, то соединение автоматически разрывается сначала одной стороной, а затем и другой.

На этом мы заканчиваем обсуждение данного вопроса, но теперь должно быть ясно, что разорвать соединение без потери данных не так просто, как это кажется на первый взгляд. Из всего сказанного можно сделать вывод, что пользователь службы должен принимать участие в решении вопроса о разъединении — транспортная подсистема не может с этим справиться самостоятельно. Обратите внимание, что хотя TCP обычно использует симметричный разрыв связи (при этом каждая сторона независимо прерывает свое соединение, отправляя пакет FIN после окончания передачи данных), веб-серверы часто передают клиентам специальный пакет RST, сообщающий о мгновенном разрыве соединения, что больше похоже на асимметричный разрыв. Это возможно только потому, что веб-сервер знаком с процедурой обмена данными. Сначала он получает запрос от клиента (единственное, что отправляет клиент), а затем отсылает ему ответ.

После отправки ответа обмен данными завершен: каждая сторона передала другой то, что требовалось. Поэтому сервер может резко разорвать соединение, отправив клиенту предупреждение. Получив его, клиент сразу же разорвет соединение. Если предупреждение не дойдет до клиента, он через какое-то время поймет, что сервер с ним больше не общается, и отсоединится. В любом случае данные будут успешно переданы.

6.2.4. Контроль ошибок и управление потоком данных

Изучив процессы установления и разрыва соединения, рассмотрим, как происходит управление соединением во время его использования. Ключевыми проблемами являются контроль ошибок и управление потоком данных. Контроль ошибок отвечает за передачу данных с необходимой степенью надежности: как правило, это означает, что данные должны доставляться без ошибок. Управление потоком состоит в согласовании скорости источника и получателя.

Оба этих вопроса мы уже обсуждали, когда говорили о канальном уровне в главе 3. На транспортном уровне используются те же механизмы. Вкратце они выглядят так.

1. Фрейм содержит код с обнаружением ошибок (например, CRC-код или контрольную сумму), с помощью которого проверяется, правильно ли была доставлена информация.

2. Фрейм содержит идентифицирующий порядковый номер и передается отправителем до тех пор, пока не придет подтверждение об успешной доставке. Это называется автоматическим запросом повторной передачи (Automatic Repeat reQuest, ARQ).

3. Число фреймов, передаваемых отправителем в любой момент времени, обычно ограниченно: передача приостанавливается, если подтверждения приходят недостаточно быстро. Если этот максимум равен одному пакету, протокол называется протоколом с остановкой и ожиданием подтверждения (stop-and-wait). Окна большего размера позволяют использовать конвейерную обработку, а также улучшить производительность при работе с длинными и быстрыми линиями.

4. Протокол раздвижного окна (sliding window) сочетает в себе все эти возможности, а также поддерживает двунаправленную передачу данных.

Если эти механизмы применяются к фреймам на канальном уровне, то возникает логичный вопрос: как это можно перенести на сегменты транспортного уровня? На практике выясняется, что эти уровни во многом копируют друг друга. Но хотя к ним и применимы одинаковые механизмы, существуют различия в их функционировании и качестве.

Чтобы проиллюстрировать функциональное различие, обратимся к обнаружению ошибок. Контрольная сумма на канальном уровне защищает фрейм, пока он передается по каналу. На транспортном уровне она защищает сегмент на всем протяжении пути. Это сквозная проверка, которая отличается от проверки на каждом канале. Существуют примеры повреждения пакетов даже внутри маршрутизаторов (Зальцер и др.; Saltzer et al., 1984). Контрольные суммы канального уровня обеспечивали защиту пакетов, пока они передвигались по каналу, но не тогда, когда они были внутри маршрутизатора. В результате мы имеем дело с некорректной доставкой, хотя проверка на каждом канале не выявила ошибок.

Этот и другие примеры позволили Зальцеру и др. сформулировать «сквозной» принцип (end-to-end argument). Согласно этому принципу, сквозная проверка на транспортном уровне необходима для корректной передачи данных; проверка на канальном уровне не является необходимой, но позволяет существенно улучшить производительность (так как иначе поврежденный пакет будет все равно проходить весь путь, что приведет к лишней нагрузке на сеть).

Чтобы продемонстрировать разницу в качестве, рассмотрим повторную передачу данных и протокол раздвижного окна. Большинство беспроводных каналов, в отличие от спутниковых, позволяют отправлять только один фрейм за единицу времени. Это значит, что произведение пропускной способности и времени задержки для канала достаточно мало и внутри канала едва ли может поместиться целый фрейм. Для лучшей производительности следует использовать окно маленького размера. К примеру, стандарт 802.11 применяет протокол с остановкой и ожиданием подтверждения. Он выполняет передачу и повторные передачи одного фрейма до тех пор, пока не придет подтверждение о его получении, и только после этого переходит к другому фрейму. Если бы размер окна был больше одного фрейма, это не повысило бы производительность, а только усложнило процесс передачи. В проводных и оптоволоконных линиях связи, таких как Ethernet (коммутируемый) и магистрали интернет-провайдеров, частота появления ошибок невелика. Это позволяет отказаться от повторных передач на канальном уровне, так как небольшое количество потерянных фреймов может быть восстановлено с помощью повторных сквозных передач.