Skip to content

Commit 8c9cf53

Browse files
committed
feat: 上传优化的SR协议及测试结果
1 parent 1aaaa0a commit 8c9cf53

33 files changed

Lines changed: 8363 additions & 10 deletions

File tree

Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ opt5=--port=10005 --flood --ber=1e-4
1111
# 设置部分
1212
SEQ_BITS=
1313
ifeq ($(SEQ_BITS),)
14-
SEQ_BITS=5
14+
SEQ_BITS=6
1515
endif
1616

1717
DATA_TIMER=
@@ -37,11 +37,11 @@ OUTPUT_DIR:=$(subst $(space),,$(OUTPUT_DIR))
3737
build: build_selectiverepeat build_stopwait build_gobackn
3838

3939
build_selectiverepeat: clean
40-
$(CC) $(CFLAGS) -DSEQ_BITS=$(SEQ_BITS) -DDATA_TIMER=$(DATA_TIMER) -DACK_TIMER=$(ACK_TIMER) -c Protocols/selectiverepeat.c
40+
$(CC) $(CFLAGS) -DSEQ_BITS=$(SEQ_BITS) -DDATA_TIMER=$(DATA_TIMER) -DACK_TIMER=$(ACK_TIMER) -c Protocols/selectiverepeat2.c
4141
$(CC) $(CFLAGS) -c protocol.c
4242
$(CC) $(CFLAGS) -c lprintf.c
4343
$(CC) $(CFLAGS) -c crc32.c
44-
$(CC) selectiverepeat.o protocol.o lprintf.o crc32.o -o datalink -lm
44+
$(CC) selectiverepeat2.o protocol.o lprintf.o crc32.o -o datalink -lm
4545

4646
build_stopwait: clean
4747
$(CC) $(CFLAGS) -DSEQ_BITS=$(SEQ_BITS) -DDATA_TIMER=$(DATA_TIMER) -DACK_TIMER=$(ACK_TIMER) -c Protocols/stopwait.c
@@ -62,11 +62,11 @@ test: test_selectiverepeat test_stopwait test_gobackn
6262

6363
test_selectiverepeat: clean
6464
mkdir -p Results/selectiverepeat/TEST_$(SEQ_BITS)BITS_$(DATA_TIMER)DATA_$(ACK_TIMER)ACK_$(TEST_TIME)S
65-
$(CC) $(CFLAGS) -DSEQ_BITS=$(SEQ_BITS) -DDATA_TIMER=$(DATA_TIMER) -DACK_TIMER=$(ACK_TIMER) -c Protocols/selectiverepeat.c
65+
$(CC) $(CFLAGS) -DSEQ_BITS=$(SEQ_BITS) -DDATA_TIMER=$(DATA_TIMER) -DACK_TIMER=$(ACK_TIMER) -c Protocols/selectiverepeat2.c
6666
$(CC) $(CFLAGS) -c protocol.c
6767
$(CC) $(CFLAGS) -c lprintf.c
6868
$(CC) $(CFLAGS) -c crc32.c
69-
$(CC) selectiverepeat.o protocol.o lprintf.o crc32.o -o Results/selectiverepeat/TEST_$(SEQ_BITS)BITS_$(DATA_TIMER)DATA_$(ACK_TIMER)ACK_$(TEST_TIME)S/datalink -lm
69+
$(CC) selectiverepeat2.o protocol.o lprintf.o crc32.o -o Results/selectiverepeat/TEST_$(SEQ_BITS)BITS_$(DATA_TIMER)DATA_$(ACK_TIMER)ACK_$(TEST_TIME)S/datalink -lm
7070
@$(foreach i,$(shell seq 1 5),\
7171
screen -dmS $(i)_datalinkA bash -c 'cd Results/selectiverepeat/TEST_$(SEQ_BITS)BITS_$(DATA_TIMER)DATA_$(ACK_TIMER)ACK_$(TEST_TIME)S; timeout $(TEST_TIME) ./datalink a $(opt$(i)) --log=$(i)_a.log; exit';\
7272
screen -dmS $(i)_datalinkB bash -c 'cd Results/selectiverepeat/TEST_$(SEQ_BITS)BITS_$(DATA_TIMER)DATA_$(ACK_TIMER)ACK_$(TEST_TIME)S; timeout $(TEST_TIME) ./datalink b $(opt$(i)) --log=$(i)_b.log; exit';\

Protocols/selectiverepeat2.c

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
#include <stdbool.h>
2+
#include <stdio.h>
3+
#include <string.h>
4+
5+
#include "../protocol.h"
6+
#include "../datalink.h"
7+
8+
typedef unsigned char seq_nr;
9+
typedef unsigned char frame_kind;
10+
11+
struct FRAME {
12+
unsigned char kind; /* FRAME_DATA */
13+
unsigned char ack;
14+
unsigned char seq;
15+
unsigned char data[PKT_LEN];
16+
unsigned int padding;
17+
};
18+
19+
struct BUFFER {
20+
unsigned char data[PKT_LEN];
21+
size_t len;
22+
};
23+
24+
/* 发送窗口相关变量 */
25+
static struct BUFFER out_buf[NR_BUFS]; /* 发送方缓存区 */
26+
static unsigned char nbuffered = 0; /* 发送缓存区被使用个数 */
27+
28+
/* 接收窗口相关变量 */
29+
static struct BUFFER in_buf[NR_BUFS]; /* 接收方缓存区 */
30+
static bool arrived[NR_BUFS]; /* 接收方缓存区状态 */
31+
32+
static seq_nr i = 0; /* 缓存区索引 */
33+
static int phl_ready = 0;
34+
static bool no_nak = true;
35+
36+
// 判断是否处于在窗口中
37+
static bool between(seq_nr a, seq_nr b, seq_nr c)
38+
{
39+
return a <= b && b < c || c < a && a <= b || b < c && c < a;
40+
}
41+
42+
// 添加校验段,发送DATA帧到物理层
43+
static void put_frame(unsigned char *frame, int len)
44+
{
45+
*(unsigned int *)(frame + len) = crc32(frame, len);
46+
send_frame(frame, len + 4);
47+
phl_ready = 0;
48+
}
49+
50+
// 根据不同类型构建帧、发送帧、处理计时器
51+
static void send_frame_datalink(frame_kind fk, seq_nr frame_nr, seq_nr frame_expected)
52+
{
53+
struct FRAME s;
54+
s.kind = fk;
55+
s.ack = (frame_expected + MAX_SEQ) % (MAX_SEQ + 1);
56+
if (fk == FRAME_DATA)
57+
{
58+
s.seq = frame_nr;
59+
memcpy(s.data, out_buf[frame_nr % NR_BUFS].data, out_buf[frame_nr % NR_BUFS].len);
60+
dbg_frame("Send DATA %d %d, ID %d\n", s.seq, s.ack, *(short *)s.data);
61+
put_frame((unsigned char *)&s, 3 + out_buf[frame_nr % NR_BUFS].len);
62+
start_timer(frame_nr % NR_BUFS, DATA_TIMER);
63+
}
64+
else
65+
{
66+
if (fk == FRAME_NAK)
67+
{
68+
s.ack = frame_expected;
69+
dbg_frame("Send NAK %d\n", frame_expected);
70+
}
71+
else
72+
dbg_frame("Send ACK %d\n", s.ack);
73+
send_frame((unsigned char *)&s, 3);
74+
}
75+
stop_ack_timer();
76+
}
77+
78+
int main(int argc, char **argv)
79+
{
80+
static seq_nr ack_expected = 0; /* 发送窗口下界 */
81+
static seq_nr frame_nr = 0; /* next_frame_to_send,即发送窗口上界 + 1 */
82+
static seq_nr frame_expected = 0; /* 接收窗口的下界 */
83+
static seq_nr too_far = NR_BUFS; /* 接收窗口的上界 + 1 */
84+
85+
int event, arg;
86+
struct FRAME f;
87+
int len = 0;
88+
89+
/* 初始化接收窗口状态,并没有被缓存的帧 */
90+
for (i = 0; i < NR_BUFS; i++) {
91+
arrived[i] = false;
92+
}
93+
94+
protocol_init(argc, argv);
95+
lprintf("Datalink using Selective-Repeat protocol designed by Zhang Keming, "
96+
"build: " __DATE__ " " __TIME__ "\n");
97+
98+
disable_network_layer();
99+
100+
while (true)
101+
{
102+
event = wait_for_event(&arg);
103+
104+
switch (event)
105+
{
106+
case NETWORK_LAYER_READY: // 网络层就绪
107+
nbuffered++;
108+
out_buf[frame_nr % NR_BUFS].len = get_packet(out_buf[frame_nr % NR_BUFS].data);
109+
send_frame_datalink(FRAME_DATA, frame_nr, frame_expected); // 发送DATA帧
110+
inc(frame_nr);
111+
break;
112+
113+
case PHYSICAL_LAYER_READY:
114+
phl_ready = 1;
115+
break;
116+
117+
case FRAME_RECEIVED:
118+
len = recv_frame((unsigned char *)&f, sizeof f);
119+
if (len < 5 && len != 3)
120+
break;
121+
if (len >= 5 && crc32((unsigned char *)&f, len) != 0) // 校验错误
122+
{
123+
dbg_event("**** Receiver Error, Bad CRC Checksum ****\n");
124+
send_frame_datalink(FRAME_NAK, 0, f.seq);
125+
break;
126+
}
127+
128+
if (f.kind == FRAME_ACK)
129+
dbg_frame("Recv ACK %d\n", f.ack);
130+
131+
if (f.kind == FRAME_DATA)
132+
{
133+
dbg_frame("Recv DATA %d %d, ID %d\n", f.seq, f.ack, *(short *)f.data);
134+
start_ack_timer(ACK_TIMER);
135+
if (between(frame_expected, f.seq, too_far) && !arrived[f.seq % NR_BUFS])
136+
{
137+
arrived[f.seq % NR_BUFS] = true;
138+
memcpy(in_buf[f.seq % NR_BUFS].data, f.data, len - 7);
139+
in_buf[f.seq % NR_BUFS].len = len - 7;
140+
while (arrived[frame_expected % NR_BUFS]) // 将接收缓冲区中连续的已收到的帧发送到网络层
141+
{
142+
put_packet(in_buf[frame_expected % NR_BUFS].data, in_buf[frame_expected % NR_BUFS].len);
143+
arrived[frame_expected % NR_BUFS] = false;
144+
inc(frame_expected);
145+
inc(too_far);
146+
start_ack_timer(ACK_TIMER);
147+
}
148+
}
149+
}
150+
151+
if (f.kind == FRAME_NAK && between(ack_expected, f.ack, frame_nr)) // 发送特定的NAK帧
152+
{
153+
dbg_frame("Recv NAK %d\n", f.ack);
154+
send_frame_datalink(FRAME_DATA, f.ack, frame_expected);
155+
break;
156+
}
157+
158+
while (between(ack_expected, f.ack, frame_nr)) // 累计确认
159+
{
160+
nbuffered--;
161+
stop_timer(ack_expected % NR_BUFS);
162+
inc(ack_expected);
163+
}
164+
break;
165+
166+
case DATA_TIMEOUT:
167+
dbg_event("---- DATA %d timeout ----\n", arg);
168+
if (!between(ack_expected, arg, frame_nr)) // 计时器中的序号只有一半,要将序号转化到窗口区间内
169+
arg += NR_BUFS;
170+
send_frame_datalink(FRAME_DATA, arg, frame_expected);
171+
break;
172+
173+
case ACK_TIMEOUT:
174+
dbg_event("---- ACK %d timeout ----\n", frame_expected);
175+
send_frame_datalink(FRAME_ACK, 0, frame_expected);
176+
break;
177+
}
178+
179+
if (nbuffered < NR_BUFS && phl_ready)
180+
enable_network_layer();
181+
else
182+
disable_network_layer();
183+
}
184+
}

0 commit comments

Comments
 (0)