Экстернат |
Транспортный уровень. Протокол управления передачей (Transmission Control Protocol — TCP)
"Скользящее окно" передатчика
Рассмотрим теперь, как передатчик меняет позицию окна передатчика. В нашем примере, допустим, передатчик посылает еще два байта (203 и 204) и получает из приемника подтверждение на успешный прием байтов 200-202. Теперь ожидают подтверждение два байта (203 и 204). Если размер окна приемника не меняется (пока еще равен 7), то передатчик может теперь сдвигать свое окно и освободить места, занятые байтами 200-202, которые могут быть использованы повторно. Рис. 10.7 показывает состояние буфера передатчика и окно передатчика перед и после этого события. Во второй части этого рисунка передатчик может теперь посылать байты с 205 до 209 (5 следующих байт).
Расширение "скользящего окна"
Если процесс приемника принимает данные быстрее, чем они поступают, размер окна может быть расширен (в буфер можно добавить свободные места). Эта ситуация может привести к увеличению (расширению) размера окна в передатчике. На Рис. 10.8 приемник прислал подтверждение еще на 2 байта (теперь ожидает подтверждения байт 205), и в то же самое время размер окна приемника увеличен до 10. Такое увеличение позволяет процессу передачи ввести дополнительно 5 байт и передать 5 байт.
Уменьшение окна передатчика
Если процесс приемника принимает данные медленнее, чем они поступают, размер окна приемника уменьшается (сжимается). На рисунке приемник принимает 5 байт (с 205 до 209); однако процесс приема берет на обслуживание только один байт — это означает, что число свободных мест уменьшается по сравнению с показанным на Рис. 10.5. до 6 (10-5+1). Он подтверждает байты с 205 до 209 (ожидающий байт 210), но информирует передатчик, что надо сжать размер своего окна и не посылать более чем 6 байтов. Если передатчик уже послал 2 байта, когда он принял новые, а получил на три больше от процесса передатчика, мы будем иметь окно и буфер, показанный на рис. 10.9
Закрытие окна передатчика
Что произойдет, если буфер приемника заполнен? В этом случае размер окна приемника имеет значение нуль. Когда это транслируется передатчику, передатчик закрывает окно (левая и правая стенки перекрываются). Передатчик не может передать ни одного байта, пока приемник не передаст значение размера окна приемника, не равное нулю.
Синдром "глупого окна"
Серьезная проблема может возникнуть при работе со "скользящим окном", когда какая-либо передающая прикладная программа медленно создает данные, либо приемная прикладная программа медленно принимает данные, либо имеют места оба случая. В любой из этих ситуаций результат заключается в посылке очень маленьких сегментов, которые уменьшают эффективность работы. Например, если TCP посылает сегмент, содержащий один байт данных, это означает, что мы посылаем дейтаграмму 41 байт (20 байт — TCP-заголовок и 20 байт — IP-заголовок), которая передает только 1 байт пользовательских данных. Соотношение заголовок/информация (41/1) указывает, что производительность сети используется очень неэффективно. Эта проблема называется синдром "глупого окна". Рассмотрим детальнее, как создается эта проблема, а затем — как она может быть решена.
Синдром, создаваемый передатчиком
Протокол передачи TCP может создать синдром "глупого окна", если он обслуживает медленную прикладную программу, которая медленно создает данные, например, 1 байт за время передачи всего окна. Прикладная программа за это время записывает один байт в буфер передачи TCP. Если передающее TCP не имеет никаких заданных инструкций, он может создать сегмент, содержащий один байт данных. Результат — передача большого числа 41-байтных сегментов, которые проходят через Интернет.
Элементарное решение — запретить TCP-передатчику передавать данные длиной 1 байт. Можно алгоритм передатчика поставить в режим ожидания момента, когда соберутся данные, чтобы послать большой блок. Как долго должно TCP ждать? Если ожидание слишком долгое, то это может замедлить процесс. А если ждать недостаточно, это может окончиться посылкой маленького сегмента.
Простое решение в случае, когда передающий процесс медленнее принимающего, состоит в том, чтобы установить оптимальную величину сегмента для передачи в линию. Естественно, что такая передача может начаться, только когда накоплен сегмент заданной величины и к этому времени получено подтверждение приема предыдущего сегмента.
Алгоритм Нагла (Nagle's algorithm)
Алгоритм Нагела прост, но решает проблему. Этот алгоритм для передатчика TCP:
- Передатчик TCP посылает первый кусок данных, приемник получает этот кусок от передающей прикладной программы, даже если это только один байт.
- После посылки первого сегмента TCP передатчик накапливает данные в выходном буфере и ждет, пока приемник TCP пришлет подтверждение или пока накопится достаточно данных для заполнения максимального размера сегмента. К этому времени TCP может передать сегмент.
- Шаг 2 может повториться для всей дальнейшей передачи. Сегмент 3 может быть послан, если получено подтверждение на сегмент 2 или накоплено достаточно данных для заполнения максимального размера сегмента.
Алгоритм Нагла позволяет учитывать и согласовывать скорость передачи пакета данных программой TCP и фактической скоростью передачи данных по сети.Если прикладная программа быстрее, чем сетевая – создается больший сегмент (максимальный сегмент). Если прикладная программа медленнее, чем сетевая, то создается сегмент, меньший, чем максимальный. В медленных глобальных сетях, где ответ идёт долго, пакеты будут посылаться реже и, следовательно, в трафике будет меньше служебной информации.
Синдром, создаваемый приемником
TCP приемника может создать синдром "глупого окна", если он обслуживает программу, которая поглощает данные медленно, например, 1 байт за один цикл чтения всего буфера. Предположим, что программа передачи создает данные в блоках 1K, но программа приемника принимает 1 байт за один цикл. Также предположим, что входной буфер TCP приема равен 4 Кбайта. Передатчик посылает 4 Кбайта данных. Приемник сохраняет их в своем буфере. Теперь его буфер полный. Он превращает размер окна в нуль, что означает, что передатчик должен прекратить передачу данных. Приложения приемника читает первый байт данных из входного буфера приемника. Теперь мы имеем 1 байт пространства во входящем буфере. TCP приемника объявляет размер окна 1 байт, который означает, что передатчик TCP, который раньше ожидал разрешение на передачу, воспримет это преобразование окна как хорошую новость и пошлет сегмент, переносящий только один байт. Процедура будет продолжаться. Один байт данных поглощается, и посылается сегмент, переносящий один байт данных. Опять мы имеем проблему эффективности.
Чтобы предотвратить создание "глупого окна" прикладной программой, которая поглощает данные медленнее, чем они пребывают, предлагаются два решения.
Первое: послать подтверждение сразу, как данные приняты правильно, но сигнал о смене размера окна посылать по мере накопления в буфере пространства для приема сегмента максимального размера или когда буфер пуст.
Второе решение — задержать передачу подтверждения. Это означает, что когда сегмент прибывает, его не надо подтверждать немедленно. Приемник ждет, пока количество пространства во входящем буфере станет подходящим, прежде чем подтвердить прибывший сегмент. Задержка подтверждения предотвращает передающий TCP от возникновения эффекта "глупого окна". После посылки данных окно останавливается. Данные не передаются до получения подтверждения. Это устраняет синдром.
Задержанное подтверждение также имеет другое преимущество: оно уменьшает трафик, поскольку приемник не подтверждает каждый сегмент. Однако его недостаток в том, что задержанное подтверждение может заставить передатчик повторно передать неподтвержденный сегмент.
Протокол находит баланс достоинств и недостатков. Он теперь определяет, что подтверждение не должно быть задержано более чем на 500 мс.