Skip to content

Instantly share code, notes, and snippets.

@rostislaved
Created October 21, 2019 08:48
Show Gist options
  • Save rostislaved/c70ba03aa9391a318a9feecb3d3e7ee0 to your computer and use it in GitHub Desktop.
Save rostislaved/c70ba03aa9391a318a9feecb3d3e7ee0 to your computer and use it in GitHub Desktop.
c
/* Протокол 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