1、发送方窗口内的序列号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧。下面是一个例子(设发送窗口尺寸为2,接收窗口尺寸为1):分析:(1) 初始态,发送方没有帧发出,发送窗口前后沿相重合。接收方0号窗口打开,等待接收0号帧;(2) 发送方打开0号窗口,表示已发出0帧但尚未确认返回信息。此时接收窗口状态不变;(3) 发送方打开0、1号窗口,表示0、1号帧均在等待确认。至此,发送方打开的窗口数已达规定限度,在未收到新的确认返回帧之前,发送方将暂停发送新的数据帧。接收窗口此时状态仍未变;(4) 接收方已收到0号帧,0号窗口关闭,1号窗口打开,表示准备接收1号帧。此时发送窗口状态不
2、变;(5) 发送方收到接收方发来的0号帧确认返回信息,关闭0号窗口,表示从重发表中删除0号帧。此时接收窗口状态仍不变;(6) 发送方继续发送2号帧,2号窗口打开,表示2号帧也纳入待确认之列。至此,发送方打开的窗口再次达到规定限度,在未收到新的确认返回帧之前,发送方将暂停发送新的数据帧,此时接收窗口状态仍不变;(7) 接收方已收到1号帧,1号窗口关闭,2号窗口打开,表示准备接收2号帧。(8) 发送方收到接收方发来的1号帧收到的确认信息,关闭1号窗口,表示从重发表中删除1号帧。此时接收窗口状态仍不变。若从滑动窗口的观点来统一看待1比特滑动窗口、后退N及选择重传三种协议,它们的差别仅在于各自窗口尺寸
3、的大小不同而已:1比特滑动窗口协议:发送窗口 = 1,接收窗口 = 1;后退n协议:发窗口 1,接收窗口 1;选择重传协议:发送窗口 1,接收窗口 1。1.3.2比特滑动窗口协议 当发送窗口和接收窗口的大小固定为1时,滑动窗口协议退化为停-等协议(stop-and-wait)。该协议规定发送方每发送一帧后就要停下来,等待接收方已正确接收的确认(acknowledgement)返回后才能继续发送下一帧。由于接收方需要判断接收到的帧是新发送的帧还是重新发送的帧,因此发送方要为每一个帧加一个序号。由于停等协议规定只有一帧完全发送成功后才能发送新的帧,因而只用1比特来编号就够了。1.3.3后退N协议任
4、何时候,若带宽与往返延迟的乘积很大,则发送方就需要一个较大的窗口。如果带宽很高的话,即使对于一个并不很长的延迟,发送方也会很快用完它的窗口,除非窗口真的非常大。如果延迟很长,那么即使带宽并不高,发送方也会用完它的窗口。这两个因子的乘积基本上说明了这条管道的容量,发送方为了达到尖峰效率,需要这条管道来马不停蹄的发送数据。这项技术称为管道化技术。使用管道化技术后,有两种方法可以用来处理错误。一种方法是回退n帧(实验一),另一种则是选择性重传(实验二)。由于停等协议要为每一个帧进行确认后才继续发送下一帧,大大降低了信道利用率,因此又提出了后退N协议。后退N协议中,发送方在发完一个数据帧后,不停下来等
5、待应答帧,而是连续发送若干个数据帧,即使在连续发送过程中收到了接收方发来的应答帧,也可以继续发送。而且,发送方在每发送完一个数据帧时都要设置超时定时器。只要在所设置的超时时间内仍收到确认帧,就要重发相应的数据帧。例如:当发送方发送了N个帧后,若发现这N帧的前一帧在计时器超时后仍未返回其确认信息,则该帧被判定为出错或丢失,此时发送方就不得不重新发送出错的这帧及其后的N帧。 从这里不难看出,后退N协议一方面因连续发送数据帧而提高了效率,但另一方面,在重传时又必须把原来已正确传送过的数据帧进行重传(仅因这些数据帧之前有一个数据帧出了错),这种做法又使传送效率降低。由此可见,若传输信道的传输质量很差,
6、因而误码率较大时,连续传送协议不一定优于停止-等待协议。此协议中的发送窗口的大小为k,接收窗口仍是1。1.4实验步骤1.4.1编写程序程序源代码如下:#include stdio.hstring.htime.hconio.hgraphics.h#define N_BACKE 2#define LEN sizeof(struct Frame)int randm(int, int); int t;int g_seq = 1;int g_pos = 0;struct Frameint err;/*出错标志*/int out;/*发送标志*/int seq;int clock;int ack; int
7、 count;/*传输次数*/struct Frame *next;*sd, *re;typedef struct Frame Fra;void Insert(Fra *, Fra *);void init()/*初始化就绪、阻塞、完成队列*/sd = NULL;re = NULL;void delay(int a)/*时间延迟函数,用于实现数据帧的动态变化*/clock_t start = clock();/*系统时间函数*/while (clock() - a * CLK_TCK count = 0;out = 0;/*已经发送标志*/seq = g_seq;/*帧序号*/clock =
8、N_BACKE;/*最大后退次数*/ack = 0;/*接受确认*/if (p-seq % t = 0)p-err = 1;/*出错标志*/elseerr = 0; next = NULL;Insert(&sd, p);g_seq+;void Insert(Fra *v, Fra *p)/*将数据帧插入到V队列中*/Fra *q;q = *v;if (*v = NULL)q = p;*v = q;while (q-next != NULL)q = q-next;q-next = p; void send(Fra *p)/*发送数据帧*/char str10;out = 1;err = 0)/*
9、发送未出错*/ack = 1;setfillstyle(1, 4);/*设置填充模式,用4号颜色红表示正确发送*/setcolor(1);circle(50 + 25 * p-seq, 150, 10);/*画圆圈表示数据帧*/floodfill(50 + 25 * p-seq, 150, 1);setcolor(2); itoa(p-seq, str, 10); outtextxy(45 + 25 * p-seq, 146, str);/*显示帧的编号*/if (p-count 0)setfillstyle(1, 5);setcolor(1);circle(50 + 25 * p-seq,
10、300, 10);floodfill(50 + 25 * p-seq, 300, 1);setcolor(2);itoa(p-outtextxy(45 + 25 * p-seq, 296, str); else/*发送出错*/setfillstyle(1, 7);/*用7号颜色表示错误的发送*/setcolor(4);outtextxy(45 + 25* p- count+;void back_send(Fra *v)/*检查超时未确认的帧*/int pos;Fra *p;p = *v;while (p !ack = 0 & p-clock = 0)/*超时未发,取得该帧标号*/g_pos = p-seq;break;else if (p-out = 1)p-clock -= 1;p = p-Fra *search(Fra *v, int num)/*查找未确认帧对应的指针*/seq = num)return p;elsep = p-int randm(int x, int y)/*随机数函数*/int k;k = rand() % (x - y) + x;return k;print(Fra *v)/*在屏幕上显示帧序列*/int size; void *buff;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1