litbaza книги онлайнРазная литератураКомпьютерные сети. 6-е изд. - Эндрю Таненбаум

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 80 81 82 83 84 85 86 87 88 ... 335
Перейти на страницу:
связанные с поломкой оборудования или случайной перезагрузкой.

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

3.3.2. Базовая схема передачи и приема данных

Получив пакет от сетевого уровня отправителя, канальный уровень формирует из него фрейм, добавляя заголовок и трейлер (см. илл. 3.1). Таким образом, фрейм состоит из встроенного пакета, некоторой служебной информации (в заголовке) и контрольной суммы (в трейлере). Затем фрейм передается канальному уровню целевого устройства. Мы будем исходить из наличия подходящих библиотечных процедур, например to_physical_layer для отправки фрейма и from_physical_layer для его получения. Они вычисляют и добавляют или проверяют контрольную сумму (обычно это делается аппаратно), так что при разработке протоколов, представленных в этом разделе, можно об этом не беспокоиться. К примеру, они могут использовать рассмотренный ранее алгоритм CRC (циклический избыточный код).

Изначально получатель ничего не должен делать, он просто ожидает. В протоколах, рассматриваемых в этой главе, ожидание событий канальным уровнем происходит путем вызова процедуры wait_for_event(&event). Эта процедура возвращает управление, только когда что-то происходит (например, получение фрейма). При этом переменная event сообщает, что именно случилось. Наборы возможных событий отличаются в разных протоколах, поэтому будут описываться для каждого протокола отдельно. Следует отметить, что на практике канальный уровень не находится в холостом цикле ожидания событий (согласно нашему допущению), а получает прерывание, когда это событие происходит. При этом он приостанавливает текущие процессы и обрабатывает полученный фрейм. Но для простоты мы проигнорируем эти детали и будем исходить из того, что канальный уровень все свое время посвящает работе с одним каналом.

Когда принимающая сторона получает фрейм, контрольная сумма вычисляется заново. Если она неверна (то есть при передаче возникли ошибки), канальный уровень получает соответствующую информацию (event=cksum_err). Если фрейм приходит без ошибок, канальному уровню об этом также сообщается (event=frame_arrival), после чего он может получить этот фрейм у физического уровня с помощью процедуры from_physical_layer. Получив неповрежденный фрейм, канальный уровень проверяет управляющую информацию, находящуюся в заголовке, и если все в порядке, часть фрейма передается сетевому уровню; заголовок фрейма не передается ни при каких обстоятельствах.

Для запрета передачи сетевому уровню любой части заголовка фрейма есть веская причина: необходимо обеспечить полное разделение сетевого и канального уровней. До тех пор пока сетевой уровень ничего не знает о формате фрейма и протоколе канального уровня, их изменения не потребуют смены программного обеспечения самого сетевого уровня. Это происходит только при установке на компьютер новой сетевой карты. Поддержание жестко заданного интерфейса между сетевым и канальным уровнями значительно упрощает разработку программ, так как протоколы различных уровней могут развиваться независимо.

На илл. 3.11 показаны некоторые объявления (на языке 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 переменной длины, в управляющих фреймах оно полностью отсутствует.

Важно понимать взаимоотношения между пакетом и фреймом (см. илл. 3.1). Сетевой уровень создает пакет, принимая сообщение от транспортного уровня и добавляя к нему свой заголовок. Пакет передается канальному уровню, который включает его в поле info исходящего фрейма. Когда целевое устройство получает фрейм, канальный уровень извлекает пакет из фрейма и передает его сетевому. Таким образом, сетевой уровень может действовать так, будто устройства обмениваются пакетами напрямую.

#define MAX_PKT 1024                                   /* определяет размер пакета в байтах

typedef enum {false, true} boolean;                    /* тип boolean */

typedef unsigned int seq_nr;                           /* порядковые номера фреймов                                                          или подтверждений */

typedef struct {unsigned char data[MAX_PKT];} packet;  /* определение пакета */

typedef 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);

/* Запретить сетевому уровню инициировать событие network_layer_ready. */

void disable_network_layer(void);

/* Макрос inc развертывается прямо в строке: циклически увеличить переменную k. */

#define inc(k) if (k < MAX_SEQ) k = k + 1; else k = 0

Илл. 3.11. Общие определения для последующих протоколов. Определения располагаются в файле protocol.h

На илл. 3.11 также перечислен ряд процедур. Это библиотечные процедуры, детали которых зависят от конкретной реализации; их внутреннее устройство мы рассматривать не будем. Как уже упоминалось ранее, процедура wait_for_event представляет собой холостой цикл ожидания какого-либо события. Процедура to_network_layer используется канальным уровнем для отправки пакетов сетевому, from_network_layer — для получения пакетов от него. Обратите внимание:

1 ... 80 81 82 83 84 85 86 87 88 ... 335
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?