Компьютерные сети. 6-е изд.
вернуться

Д. Таненбаум Э. С., Фимстер Н. , Уэзеролл

Шрифт:

Хотя в протоколе 5 фреймы, поступившие после ошибки, не буферизируются получателем, отправитель должен хранить отправленные фреймы в своем буфере, пока не получит для них подтверждение.

Если поступает подтверждение на фрейм n, фреймы n – 1, n – 2 (и все предыдущие фреймы) автоматически считаются подтвержденными. Такой тип подтверждения называется кумулятивным (cumulative acknowledgement). Он наиболее полезен в случае потери или повреждения предыдущих подтверждений. Получив подтверждение, канальный уровень проверяет, не освободился ли у него буфер (то есть не появилось ли свободное место в окне). Если место доступно, то заблокированному ранее сетевому уровню можно снова разрешить инициировать события network_layer_ready.

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

/* П ротокол 5 (конвейерный) допускает наличие нескольких неподтвержденных фреймов. Отправитель может передать до MAX_SEQ фреймов, не ожидая подтверждения. Кроме того, в отличие от предыдущих протоколов, не предполагается, что у сетевого уровня всегда есть новые пакеты. При появлении нового пакета сетевой уровень инициирует событие network_layer_ready. */

#define MAX_SEQ 7

typedef enum {frame_arrival, cksum_err, timeout, network_layer_ready} event_type;

#include "protocol.h"

static boolean between(seq_nr a, seq_nr b, seq_nr c)

{

/* Возвращает true, если a <=b < c циклично; иначе false.

if (((a <= b) && (b < c)) || ((c < a) && (a <= b)) || ((b < c) && (c < a)))

return(true);

else

return(false);

}

static void send_data(seq_nr frame_nr, seq_nr frame_expected, packet buffer[ ])

{

/* Подготовить и послать информационный фрейм. */

frame s; /* временная переменная */

s.info = buffer[frame_nr]; /* вставить пакет во фрейм */

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

s.ack = (frame_expected + MAX_SEQ) % (MAX_SEQ + 1); /* подтверждение, вкладываемое во фрейм данных */

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

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

}

void protocol5(void)

{

seq_nr next_frame_to_send; /* MAX_SEQ > 1; используется для исходящего потока */

seq_nr ack_expected; /* самый старый неподтвержденный фрейм */

seq_nr frame_expected; /* следующий фрейм, ожидаемый во входящем потоке */

frame r; /* временная переменная */

packet buffer[MAX_SEQ+1]; /* буферы для исходящего потока */

seq_nr nbuffered; /* количество использующихся в данный момент выходных буферов */

seq_nr i; /* индекс массива буферов */

event_type event;

enable_network_layer; /* разрешить события network_layer_ready */

ack_expected = 0; /* номер следующего ожидаемого входящего подтверждения */

next_frame_to_send = 0; /* номер следующего посылаемого фрейма */

frame_expected = 0; /* номер ожидаемого входящего фрейма */

nbuffered = 0; /* вначале буфер пуст */

while (true) {

wait_for_event(&event); /* четыре возможных события: см. event_type выше */

switch(event) {

case network_layer_ready: /* у сетевого уровня есть пакет для передачи */

/* Получить, сохранить и передать новый фрейм

from_network_layer(&buffer[next_frame_to_send]); /* получить новый пакет у сетевого уровня */

nbuffered = nbuffered + 1; /* увеличить окно отправителя */

send_data(next_frame_to_send, frame_expected, buffer); /* передать фрейм */

inc(next_frame_to_send); /* увеличить верхний край окна отправителя */

break;

case frame_arrival: /* пришел фрейм с данными или с подтверждением */

from_physical_layer(&r); /* получить пришедший фрейм у физического уровня */

  • Читать дальше
  • 1
  • ...
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • ...

Private-Bookers - русскоязычная библиотека для чтения онлайн. Здесь удобно открывать книги с телефона и ПК, возвращаться к сохраненной странице и держать любимые произведения под рукой. Материалы добавляются пользователями; если считаете, что ваши права нарушены, воспользуйтесь формой обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • help@private-bookers.win