В качестве иллюстрации приводится рис. 3.14, на котором показана программная реализация нескольких таймеров. Предположим, что часы изменяют свое состояние каждые 1 мс. Пусть начальное значение реального времени будет 10:00:00.000 и имеются три таймера тайм-аутов, установленные на время 10:00:00.005, 10:00:00.013 и 10:00:00.019. Каждый раз, когда аппаратные часы изменяют свое значение, реальное время обновляется и счетчик этих изменений в голове списка уменьшается на единицу. Когда значение счетчика становится равным нулю, инициируется тайм-аут, а узел удаляется из списка, как показано на рис. 3.14,
хотя при работе процедур start_timer и stop_timer требуется сканирование списка. В протоколе у данных процедур имеется входной параметр, означающий номер кадра, таймер которого нужно запустить или остановить.
Рис. 3.14. Программная симуляция работы нескольких таймеров
3.4.3. Протокол с выборочным повтором
Протокол с возвратом на
В этом протоколе и отправитель, и получатель работают с окнами неподтвержденных и допустимых номеров кадров соответственно. Размер окна отправителя начинается с нуля и растет до некоторого определенного уровня. Размер окна получателя, напротив, всегда фиксированного размера. Получатель должен иметь буфер для каждого кадра, номер которого находится в пределах окна. С каждым буфером связан бит, показывающий, занят буфер или свободен. Когда прибывает кадр, функция between проверяет, попал ли его порядковый номер в окно. Если да, то кадр принимается и хранится в буфере. Это действие производится независимо от того, является ли данный кадр следующим кадром, ожидаемым сетевым уровнем. Он должен храниться на канальном уровне до тех пор, пока все предыдущие кадры не будут переданы сетевому уровню в правильном порядке. Алгоритм протокола показан в листинге 3.7.
Листинг 3.7. Протокол скользящего окна с выборочным повтором
Листинг 3.7
Листинг 3.7
Способность протокола принимать кадры в произвольном порядке накладывает дополнительные ограничения на порядковые номера кадров по сравнению с протоколами, в которых все пакеты принимались строго по порядку номеров. Проще всего проиллюстрировать это на примере. Предположим, что порядковый номер кадра состоит из 3 бит, так что отправитель может посылать до семи кадров, прежде чем перейти в режим ожидания подтверждения. Начальное состояние окон отправителя и получателя изображено на рис. 3.15,
Рис. 3.15. Пример работы протокола: а — начальная ситуация при размере окна 7;
Именно в этот момент происходит какое-нибудь бедствие, например молния ударяет в телефонный столб и стирает все подтверждения. Протокол обязан отработать правильно, несмотря ни на какие чрезвычайные ситуации. Отправитель, не дождавшись подтверждений, посылает повторно кадр 0. К сожалению, кадр 0 попадает в новое окно и поэтому принимается получателем (рис. 3.15, б). Получатель снова отправляет подтверждение для кадра 6, поскольку были приняты все кадры с 0 по 6.
Отправитель с радостью узнает, что все переданные им кадры успешно достигли адресата, поэтому он тут же передает кадры 7, 0, 1, 2, 3, 4 и 5. Кадр 7 принимается получателем, и содержащийся в нем пакет передается сетевому уровню. Сразу после этого принимающий канальный уровень проверяет наличие кадра 0, обнаруживает его и передает старый буферизированный пакет сетевому уровню как новый. Таким образом, сетевой уровень получает неверный пакет; это означает, что протокол со своей задачей не справился.
Причина неудачи в том, что при сдвиге приемного окна новый интервал допустимых номеров кадров перекрыл старый интервал. Соответственно, присылаемый набор кадров может содержать как новые кадры (если все подтверждения были получены), так и повторно высланные старые кадры (если подтверждения были потеряны). У принимающей стороны нет возможности отличить одну ситуацию от другой.