Читаем Компьютерные сети. 6-е изд. полностью

                  from_network_layer(&buffer); /* получить следующий пакет у сетевого уровня */

                  inc(next_frame_to_send);     /* инвертировать порядковый номер посылаемого фрейма */

           }

     }

     s.info = buffer;                          /* подготовить фрейм для передачи */

     s.seq = next_frame_to_send;               /* вставить порядковый номер во фрейм */

     s.ack = 1 – frame_expected;               /* порядковый номер последнего полученного фрейма */

     to_physical_layer(&s);                    /* передать фрейм */

     start_timer(s.seq);                       /* запустить таймер ожидания подтверждения */

}

}

Илл. 3.16. Однобитный протокол раздвижного окна

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

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

Теперь изучим протокол 4 и посмотрим, насколько он устойчив к нестандартным ситуациям. Представим, что устройство A пытается послать фрейм 0 устройству B, при этом B пытается отправить A фрейм 0. Предположим, что на A установлен слишком короткий период ожидания подтверждения. Соответственно, A посылает серию одинаковых фреймов со значениями полей seq = 0 и ack = 1.

Когда первый неповрежденный фрейм придет на устройство B, он будет принят и значение переменной frame_expected будет равно 1. Все последующие входящие фреймы будут проигнорированы, поскольку B теперь ожидает фрейм с порядковым номером 1, а не 0. Более того, поскольку у всех дубликатов значение поля ack = 1, а устройство B продолжает ожидать подтверждения для фрейма 0, оно не станет запрашивать новый пакет у своего сетевого уровня.

В ответ на каждый отвергнутый дубликат, присылаемый устройством A, B посылает фрейм, содержащий поля seq = 0 и ack = 0. Наконец, один из этих фреймов принимается A, в результате чего A переходит к передаче следующего пакета. Никакая комбинация потерянных фреймов или преждевременно истекших интервалов ожидания не может заставить этот протокол ни выдать сетевому уровню дубликат пакета, ни пропустить пакет, ни зависнуть. Протокол работает корректно.

Однако отношения между протоколами могут быть довольно непростыми. Если обе стороны одновременно вышлют друг другу начальный пакет, возникает запутанная ситуация, представленная на илл. 3.17. В левой части рисунка показан случай нормального функционирования протокола. Правая часть демонстрирует отклонение. Если B ожидает первый фрейм от A, прежде чем послать свой первый фрейм, то последовательность будет как в левой части рисунка (а). При этом принимается каждый фрейм.

Но если A и B одновременно начнут передачу, их первые фреймы пересекутся и канальные уровни попадут в ситуацию (б). В ситуации (а) с каждым фреймом приходит новый пакет и дубликатов нет. В случае (б) половина фреймов содержит дубликаты, несмотря на то что ошибок в канале связи не было. Причиной может стать преждевременный тайм-аут, даже если одна сторона явно начинает диалог первой. Получается, если время ожидания истечет слишком быстро, фрейм может быть послан три и более раза, приводя к ненужной трате ценных ресурсов.

Илл. 3.17. Два сценария для протокола 4. (а) Нормальная ситуация. (б) Нештатная ситуация. Обозначения в скобках: (seq, ack, номер пакета). Звездочка показывает, что сетевой уровень принял пакет

Протокол с возвратом к n

Перейти на страницу:

Похожие книги