Компьютерные сети. 6-е изд.
Шрифт:
Необходимо, чтобы протокол выполнялся без ошибок, а нумерация не занимала много места в заголовке фрейма, поскольку соединение должно использоваться эффективно. Возникает вопрос: каково минимальное количество битов, достаточное для порядкового номера фрейма? В зависимости от протокола можно выделить один или несколько битов (или байтов). Важно, чтобы номера были достаточно большими для правильной работы протокола, иначе он будет бесполезен.
Единственная неопределенность в данном протоколе может возникнуть между фреймом m и следующим за ним фреймом m + 1. Если m потерян или поврежден, получатель не подтвердит его и отправитель повторит передачу. Когда он будет успешно принят, получатель отправит подтверждение. Именно здесь находится источник потенциальной проблемы. В зависимости от наличия подтверждения отправитель дублирует фрейм m или передает новый фрейм m + 1.
На стороне отправителя событием, запускающим передачу фрейма m + 1, является получение подтверждения доставки фрейма m. Но это означает, что фрейм m – 1 уже передан и подтверждение его доставки отправлено и получено. В противном случае протокол не стал бы посылать новый фрейм. Следовательно, неопределенность может возникнуть только между двумя соседними фреймами.
Таким образом, для нумерации фрейма достаточно всего одного бита информации (со значением 0 или 1). В каждый момент времени получатель ожидает прибытия фрейма с определенным порядковым номером. Фрейм с верным номером принимается, передается сетевому уровню, затем отправляется подтверждение его получения. Номер следующего ожидаемого фрейма увеличивается по модулю 2 (то есть 0 становится 1, а 1 — 0). Фрейм с неверным номером отбрасывается как дубликат. Однако последнее подтверждение повторяется, чтобы сообщить отправителю, что фрейм получен полностью.
Пример такого протокола представлен на илл. 3.14. Протокол, в котором отправитель ожидает положительного подтверждения, прежде чем перейти к пере-
/* Протокол 3 (PAR) обеспечивает симплексную передачу данных по ненадежному каналу.
#define MAX_SEQ 1 /* в протоколе 3 должно быть равно 1 */
typedef enum {frame_arrival, cksum_err, timeout} event_type;
#include "protocol.h"
void sender3(void)
{
seq_nr next_frame_to_send; /* порядковый номер следующего исходящего фрейма */
frame s; /* временная переменная */
packet buffer; /* буфер для исходящего пакета */
event_type event;
next_frame_to_send = 0; /* инициализация исходящих последовательных номеров */
from_network_layer(&buffer); /* получить первый пакет у сетевого уровня */
while (true) {
s.info = buffer; /* сформировать фрейм для передачи */
s.seq = next_frame_to_send; /* вставить порядковый номер во фрейм */
to_physical_layer(&s); /* послать фрейм по каналу */
start_timer(s.seq); /* запустить таймер ожидания подтверждения */
wait_for_event(&event); /* ждать событие frame_arrival, cksum_err или timeout */
if (event == frame_arrival) {
from_physical_layer(&s); /* получить подтверждение */
if (s.ack == next_frame_to_send) {
stop_timer(s.ack); /* остановить таймер
from_network_layer(&buffer); /* получить следующий исходящий пакет */
inc(next_frame_to_send); /* инвертировать значение переменной next_frame_to_send */
}
}
}
}
void receiver3(void)
{
seq_nr frame_expected;
frame r, s;
event_type event;
frame_expected = 0;
while (true) {
wait_for_event(&event); /* ожидание возможных событий: frame_arrival, cksum_err */
if (event == frame_arrival) { /* пришел неповрежденный фрейм */
from_physical_layer(&r); /* получить пришедший фрейм */
if (r.seq == frame_expected) { /* именно этот фрейм и ожидался */
to_network_layer(&r.info); /* передать данные сетевому уровню */
inc(frame_expected); /* в следующий раз ожидать фрейм с другим порядковым номером */
}
s.ack = 1 – frame_expected; /* номер фрейма, для которого посылается подтверждение */
to_physical_layer(&s); /* отправить подтверждение */
}
}
}
Илл. 3.14. Протокол с положительным подтверждением и повторной передачей
сылке следующего фрейма, часто называется PAR (Positive Acknowledgement with Retransmission — положительное подтверждение с повторной передачей) или ARQ (Automatic Repeat reQuest — автоматический запрос повторной передачи). Подобно протоколу 2, он передает данные только в одном направлении.
Протокол 3 отличается от своих предшественников тем, что и отправитель, и получатель содержат переменную, значение которой хранится, пока канальный уровень находится в режиме ожидания. Отправитель запоминает номер следующего фрейма в переменной next_frame_to_send, а получатель записывает номер следующего ожидаемого фрейма в переменной frame_expected. Каждый протокол имеет короткую фазу инициализации перед началом бесконечного цикла.
После передачи фрейма отправитель запускает таймер. Если он уже работал, он перезапускается для отсчета нового полного интервала времени. Этот интервал должен быть достаточно большим, чтобы даже при наихудшем сценарии фрейм успел дойти до получателя, тот успел его обработать и подтверждение вернулось к отправителю. Только по истечении отведенного времени можно предположить потерю фрейма или его подтверждения и отправить дубликат. Если интервал слишком короткий, то передающее устройство будет повторно посылать слишком много фреймов, в которых нет необходимости. Хотя лишние фреймы в данном случае не повлияют на правильность приема данных, это снизит производительность системы.
После передачи фрейма отправитель запускает таймер и ждет какого-либо события. Возможны три ситуации: либо придет неповрежденный фрейм подтверждения, либо будет получен поврежденный фрейм подтверждения, либо просто истечет интервал времени. В первом случае отправитель возьмет у сетевого уровня следующий пакет и разместит его в буфере поверх предыдущего, а также увеличит порядковый номер фрейма. Если же прибудет поврежденный фрейм подтверждения или время истечет, то ни буфер, ни номер не будут изменены и будет отправлен дубликат фрейма. В любом случае затем посылается содержимое буфера (следующий пакет либо дубликат предыдущего).
Когда неповрежденный фрейм прибывает к получателю, проверяется его номер. Если это не дубликат, то фрейм принимается и передается сетевому уровню, после чего формируется подтверждение. Дубликаты и поврежденные фреймы на сетевой уровень не передаются, но при их получении подтверждается прибытие последнего правильного фрейма, благодаря чему отправитель понимает, что нужно перейти к следующему фрейму или повторить передачу поврежденного.
3.4. Повышение эффективности