Э. Таненбаум, Д. Уэзеролл - Компьютерные сети (1114668), страница 70
Текст из файла (страница 70)
В приводимых в данной главе примерах протоколов ожидание событий уровнем передачи данных обозначается вызовом процедуры wait_for_event(&event). Эта процедура возвращает управление, только когда что-то происходит (например, прибывает кадр). При этом переменная event сообщает, что именнослучилось. Наборы возможных событий отличаются в разных протоколах и поэтомубудут описываться для каждого протокола отдельно. Следует заметить, что в действительности канальный уровень не находится в холостом цикле ожидания событий, как3.3. Элементарные протоколы передачи данных на канальном уровне 241мы предположили, а получает прерывание, когда это событие происходит.
При этомон приостанавливает свои текущие процессы и обрабатывает пришедший кадр. Темне менее для простоты мы проигнорируем эти детали и предположим, что канальныйуровень все свое время посвящает работе с одним каналом.Листинг 3.1. Общие объявления для последующих протоколов. Объявлениярасполагаются в файле protocol.h#define MAX_PKT 1024typedeftypedeftypedeftypedef/* определяет размер пакета в байтах */enum {false, true} boolean;/* тип boolean */unsigned int seq_nr;/* порядковые номера кадров или подтверждений */struct {unsigned char data[MAX_PKT];} packet; /* определение пакета */enum {data, ack, nak} frame_kind; /* определение типа пакета */typedef struct {frame_kind kind;seq_nr seq;seq_nr ack;packet info;} frame;/*/*/*/*/*кадры, транспортируемые на данном уровне*/тип кадра */порядковый номер */номер подтверждения */пакет сетевого уровня *//* ожидать события и вернуть тип события в переменной event */void wait_for_event(event_type *event);/* получить пакет у сетевого уровня для передачи по каналу */void from_network_layer(packet *p);/* передать информацию из полученного пакета сетевому уровню */void to_network_layer(packet *p);/* получить пришедший пакет у физического уровня и скопировать его в r */void from_physical_layer(frame *r);/* передать кадр физическому уровню для передачи */void to_physical_layer(frame *s);/* запустить таймер и разрешить событие timeout */void start_timer(seq_nr k);/* остановить таймер и запретить событие timeout */void stop_timer(seq_nr k);/* запустить вспомогательный таймер и разрешить событие ack_timeout */void start_ack_timer(void);/* остановить вспомогательный таймер и запретить событие ack_timeout */void stop_ack_timer(void);/* разрешить сетевому уровню инициировать событие network_layer_ready */void enable_network_layer(void);продолжение 242 Глава 3.
Канальный уровеньЛистинг 3.1 (продолжение)/* запретить сетевому уровню инициировать событие network_layer_ready */void disable_network_layer(void);/* макрос inc развертывается прямо в строке: Циклически увеличить переменную k */#define inc(k) if (k < MAX_SEQ) k = k + 1; else k = 0Когда принимающая машина получает кадр, контрольная сумма вычисляется заново. Если контрольная сумма в кадре неверна (то есть при передаче возникли ошибки),то канальный уровень получает соответствующую информацию (event=cksum_err).Если кадр прибывает в целости, канальному уровню об этом также сообщается(event=frame_arrival), после чего он может получить этот кадр у физического уровняс помощью процедуры from_physical_layer. Получив неповрежденный кадр, канальныйуровень проверяет управляющую информацию, находящуюся в заголовке кадра,и если все в порядке, часть этого кадра передается сетевому уровню.
Заголовок кадране передается сетевому уровню ни при каких обстоятельствах.Для запрета передачи сетевому уровню любой части заголовка кадра есть вескаяпричина: поддержание полного разделения сетевого и канального уровней. До техпор пока сетевой уровень ничего не знает о формате кадра и протоколе канальногоуровня, изменения формата и протокола не потребуют изменений программного обеспечения сетевого уровня.
Это происходит при установке в компьютер новой сетевойкарты. Поддержание строгого интерфейса между сетевым и канальным уровнямизначительно упрощает разработку программ, так как протоколы различных уровнеймогут развиваться независимо.В листинге 3.1 показаны некоторые объявления (на языке C), общие для многихпротоколов, обсуждаемых ниже. Определены пять типов данных: boolean, seq_nr, packet,frame_kind и frame. Тип boolean представляет собой перечисляемый тип, переменные которого могут принимать значения true или false. Тип seq_nr является целым без знака,используемым для нумерации кадров. Эти последовательные номера могут приниматьзначения от 0 до числа MAX_SEQ включительно, которое определяется в каждом протоколе, использующем его.
Тип packet является единицей информации, используемойпри обмене информацией между сетевым и канальным уровнями одной машины илидвумя равноранговыми сетевыми уровнями. В нашей модели пакет всегда состоит изMAX_PKT байт, хотя на практике он обычно имеет переменную длину.Структура frame состоит из четырех полей: kind, seq, ack и info, первые три из которых содержат управляющую информацию, а последнее может содержать данные,которые необходимо передать. Эти три управляющих поля вместе называются заголовком кадра (frame header).Поле kind сообщает о наличии данных в кадре, так как некоторые протоколыотличают кадры, содержащие только управляющую информацию, от кадров, содержащих также и данные.
Поля seq и ack используются соответственно для храненияпоследовательного номера кадра и подтверждения. Подробнее их использование будетописано ниже. Поле данных кадра, info, содержит один пакет. В управляющем кадреполе info не используется. В реальной жизни используется поле info переменной длины, полностью отсутствующее в управляющих кадрах.Важно понимать взаимоотношения между пакетом и кадром. Сетевой уровеньсоздает пакет, принимая сообщение от транспортного уровня и добавляя к нему за-3.3. Элементарные протоколы передачи данных на канальном уровне 243головок сетевого уровня.
Этот пакет передается канальному уровню, который включает его в поле info исходящего кадра. Когда кадр прибывает на пункт назначения,канальный уровень извлекает пакет из кадра и передает его сетевому уровню. Такимобразом, сетевой уровень может действовать так, как будто машины обмениваютсяпакетами напрямую.В листинге 3.1 также перечислен ряд процедур. Это библиотечные процедуры,детали которых зависят от конкретной реализации, и их внутреннее устройствомы рассматривать не будем.
Как уже упоминалось ранее, процедура wait_for_eventпредставляет собой холостой цикл ожидания какого-нибудь события. Процедурыto_network_layer и from_network_layer используются канальным уровнем для передачипакетов сетевому уровню и для получения пакетов от сетевого уровня соответственно.Обратите внимание: процедуры from_physical_layer и to_physical_layer используются дляобмена кадрами между канальным и физическим уровнями, тогда как процедуры to_network_layer и from_network_layer применяются для передачи пакетов между канальными сетевым уровнями. Другими словами, процедуры to_network_layer и from_network_layerотносятся к интерфейсу между уровнями 2 и 3, тогда как процедуры from_physical_layerи to_physical_layer относятся к интерфейсу между уровнями 1 и 2.В большинстве протоколов предполагается использование ненадежного канала,который может случайно потерять целый кадр.
Для обработки подобных ситуацийпередающий канальный уровень, посылая кадр, запускает таймер. Если за установленный интервал времени ответ не получен, таймер воспринимает это как тайм-аут,и канальный уровень получает сигнал прерывания.В наших примерах протоколов этот сигнал реализован в виде значения event=timeout,возвращаемого процедурой wait_for_event. Для запуска и остановки таймера используются процедуры start_timer и stop_timer соответственно. Событие timeout может произойти, только если запущен таймер, но stop_timer еще не была вызвана.