-
-
Save rostislaved/c70ba03aa9391a318a9feecb3d3e7ee0 to your computer and use it in GitHub Desktop.
c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Протокол 4 (скользящее окно) является дуплексным. */ | |
#define MAX_SEQ 1 /* в протоколе 4 должно быть равно 1 */ | |
typedef enum { frame_arrival, cksum_err, timeout } event_type; | |
#include "protocol.h" | |
void protocol4(void) | |
// продолжение 254 Глава 3. Канальный уровень Листинг 3.5 (продолжение) | |
{ | |
seq_nr next_frame_to_send; /* только 0 или 1 */ | |
seq_nr frame_expected; /* только 0 или 1 */ | |
frame r, s; /* временная переменная */ | |
packet buffer; /* текущий посланный пакет */ | |
event_type event; | |
next_frame_to_send = 0; /* номер следующего кадра в исходящем потоке */ | |
frame_expected = 0; /* номер ожидаемого кадра */ | |
from_network_layer(&buffer); /* получить первый пакет у сетевого уровня */ | |
s.info = buffer; /* подготовить первый кадр для передачи */ | |
s.seq = next_frame_to_send; /* вставить порядковый номер в кадр */ | |
s.ack = | |
1 - frame_expected; /* подтверждение, посылаемое "верхом" на кадре данных | |
*/ | |
to_physical_layer(&s); /* послать кадр по каналу */ | |
start_timer(s.seq); /* запустить таймер ожидания подтверждения */ | |
while (true) { | |
wait_for_event(&event); /* ждать возможного события: frame_arrival, */ | |
/* cksum_err или timeout */ | |
if (event == frame_arrival) { /* кадр прибыл в целости */ | |
from_physical_layer(&r); /* получить кадр */ | |
if (r.seq == frame_expected) { | |
/* обработать входящий поток кадров */ | |
to_network_layer(&r.info); /* передать пакет сетевому уровню */ | |
inc(frame_expected); /* инвертировать порядковый номер кадра, */ | |
/* ожидаемого в следующий раз */ | |
} | |
if (r.ack == | |
next_frame_to_send) { /* обработать исходящий поток кадров */ | |
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); /* запустить таймер ожидания подтверждения */ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment