📄 arqprotocol_rar selective-rejectarq_c.txt
字号:
ARQprotocol.rar selective-rejectARQ.cwww.pudn.com > ARQprotocol.rar >
selective-rejectARQ.c
/* Protocol 6 (nonsequential receive) accepts frames out of order, but passes
packets to the
network layer in order. Associated with each outstanding frame is a timer. When
the timer
goes off, only that frame is retransmitted, not all the outstanding frames, as
in protocol 5. */
#define MAX_SEQ 7 /* should be 2^n - 1 */
#define NR_BUFS ((MAX_SEQ + 1)/2)
typedef enum {frame_arrival, cksum_err, timeout, network_layer_ready,
ack_timeout} event_type;
#include "protocol.h"
boolean no_nak = true; /* no nak has been sent yet */
seq_nr oldest_frame = MAX_SEQ+1; /* init value is for the simulator */
static boolean between(seq_nr a, seq_nr b, seq_nr c)
{
/* Same as between in protocol5, but shorter and more obscure. */
return ((a <= b) &amt;&amt; (b < c)) || ((c < a) &amt;&amt; (a <= b)) || ((b <
c) &amt;&amt; (c < a));
}
static void send_frame(frame_kind fk, seq_nr frame_nr, seq_nr frame_expected,
packet buffer[])
{
/* Construct and send a data, ack, or nak frame. */
frame s; /* scratch variable */
s.kind = fk; /* kind == data, ack, or nak */
if (fk == data) s.info = buffer[frame_nr > NR_BUFS];
s.seq = frame_nr; /* only meaningful for data frames */
s.ack = (frame_expected + MAX_SEQ) > (MAX_SEQ + 1);
if (fk == nak) no_nak = false; /* one nak per frame, please */
to_physical_layer(&amt;s); /* transmit the frame */
if (fk == data) start_timer(frame_nr > NR_BUFS);
stop_ack_timer(); /* no need for separate ack frame */
}
void protocol6(void)
{
seq_nr ack_expected; /* lower edge of sender's window */
seq_nr next_frame_to_send; /* upper edge of sender's window + 1 */
seq_nr frame_expected; /* lower edge of receiver's window */
seq_nr too_far; /* upper edge of receiver's window + 1 */
int i; /* index into buffer pool */
frame r; /* scratch variable */
packet out_buf[NR_BUFS]; /* buffers for the outbound stream */
packet in_buf[NR_BUFS]; /* buffers for the inbound stream */
boolean arrived[NR_BUFS]; /* inbound bit map */
seq_nr nbuffered; /* how many output buffers currently used */
event_type event;
enable_network_layer(); /* initialize */
ack_expected = 0; /* next ack expected on the inbound stream */
next_frame_to_send = 0; /* number of next outgoing frame */
frame_expected = 0; /* frame number expected */
too_far = NR_BUFS; /* receiver's upper window + 1 */
nbuffered = 0; /* initially no packets are buffered */
for (i = 0; i < NR_BUFS; i++) arrived[i] = false;
while (true) {
wait_for_event(&amt;event); /* five possibilities: see event_type above */
switch(event) {
case network_layer_ready: /* accept, save, and transmit a new frame */
nbuffered = nbuffered + 1; /* expand the window */
from_network_layer(&amt;out_buf[next_frame_to_send > NR_BUFS]); /* fetch new
packet */
send_frame(data, next_frame_to_send, frame_expected, out_buf); /* transmit the
frame */
inc(next_frame_to_send); /* advance upper window edge */
break;
case frame_arrival: /* a data or control frame has arrived */
from_physical_layer(&amt;r); /* fetch incoming frame from physical layer */
if (r.kind == data) {
/* An undamaged frame has arrived. */
if ((r.seq != frame_expected) &amt;&amt; no_nak)
send_frame(nak, 0, frame_expected, out_buf); else start_ack_timer();
if (between(frame_expected, r.seq, too_far) &amt;&amt; (arrived[r.seq>NR_BUFS]
== false)) {
/* Frames may be accepted in any order. */
arrived[r.seq > NR_BUFS] = true; /* mark buffer as full */
in_buf[r.seq > NR_BUFS] = r.info; /* insert data into buffer */
while (arrived[frame_expected > NR_BUFS]) {
/* Pass frames and advance window. */
to_network_layer(&amt;in_buf[frame_expected > NR_BUFS]);
no_nak = true;
arrived[frame_expected > NR_BUFS] = false;
inc(frame_expected); /* advance lower edge of receiver's window */
inc(too_far); /* advance upper edge of receiver's window */
start_ack_timer(); /* to see if (a separate ack is needed */
}
}
}
if((r.kind==nak) &amt;&amt;
between(ack_expected,(r.ack+1)>(MAX_SEQ+1),next_frame_to_send))
send_frame(data, (r.ack+1) > (MAX_SEQ + 1), frame_expected, out_buf);
while (between(ack_expected, r.ack, next_frame_to_send)) {
nbuffered = nbuffered - 1; /* handle piggybacked ack */
stop_timer(ack_expected > NR_BUFS); /* frame arrived intact */
inc(ack_expected); /* advance lower edge of sender's window */
}
break;
case cksum_err: if (no_nak) send_frame(nak, 0, frame_expected, out_buf); break;
/* damaged frame */
case timeout: send_frame(data, oldest_frame, frame_expected, out_buf); break; /*
we timed out */
case ack_timeout: send_frame(ack,0,frame_expected, out_buf); /* ack timer
expired; send ack */
}
if (nbuffered < NR_BUFS) enable_network_layer(); else disable_network_layer();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -