滑动窗口协议的模拟文档格式.docx

上传人:b****6 文档编号:18563988 上传时间:2022-12-28 格式:DOCX 页数:10 大小:81.83KB
下载 相关 举报
滑动窗口协议的模拟文档格式.docx_第1页
第1页 / 共10页
滑动窗口协议的模拟文档格式.docx_第2页
第2页 / 共10页
滑动窗口协议的模拟文档格式.docx_第3页
第3页 / 共10页
滑动窗口协议的模拟文档格式.docx_第4页
第4页 / 共10页
滑动窗口协议的模拟文档格式.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

滑动窗口协议的模拟文档格式.docx

《滑动窗口协议的模拟文档格式.docx》由会员分享,可在线阅读,更多相关《滑动窗口协议的模拟文档格式.docx(10页珍藏版)》请在冰豆网上搜索。

滑动窗口协议的模拟文档格式.docx

不同的滑动窗口协议窗口大小一般不同。

发送方窗口内的序列号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧。

下面举一个例子(假设发送窗口尺寸为2,接收窗口尺寸为1):

分析:

①初始态,发送方没有帧发出,发送窗口前后沿相重合。

接收方0号窗口打开,等待接收0号帧;

②发送方打开0号窗口,表示已发出0帧但尚确认返回信息。

此时接收窗口状态不变;

③发送方打开0、1号窗口,表示0、1号帧均在等待确认之列。

至此,发送方打开的窗口数已达规定限度,在未收到新的确认返回帧之前,发送方将暂停发送新的数据帧。

接收窗口此时状态仍未变;

④接收方已收到0号帧,0号窗口关闭,1号窗口打开,表示准备接收1号帧。

此时发送窗口状态不变;

⑤发送方收到接收方发来的0号帧确认返回信息,关闭0号窗口,表示从重发表中删除0号帧。

此时接收窗口状态仍不变;

⑥发送方继续发送2号帧,2号窗口打开,表示2号帧也纳入待确认之列。

至此,发送方打开的窗口又已达规定限度,在未收到新的确认返回帧之前,发送方将暂停发送新的数据帧,此时接收窗口状态仍不变;

⑦接收方已收到1号帧,1号窗口关闭,2号窗口打开,表示准备接收2号帧。

⑧发送方收到接收方发来的1号帧收毕的确认信息,关闭1号窗口,表示从重发表中删除1号帧。

此时接收窗口状态仍不变。

若从滑动窗口的观点来统一看待1比特滑动窗口、后退n及选择重传三种协议,它们的差别仅在于各自窗口尺寸的大小不同而已。

1比特滑动窗口协议:

发送窗口=1,接收窗口=1;

后退n协议:

发窗口>

1,接收窗口>

1;

选择重传协议:

发送窗口>

1,接收窗口>

1。

(2).1比特滑动窗口协议

当发送窗口和接收窗口的大小固定为1时,滑动窗口协议退化为停等协议(stop-and-wait)。

该协议规定发送方每发送一帧后就要停下来,等待接收方已正确接收的确认(acknowledgement)返回后才能继续发送下一帧。

由于接收方需要判断接收到的帧是新发的帧还是重新发送的帧,因此发送方要为每一个帧加一个序号。

由于停等协议规定只有一帧完全发送成功后才能发送新的帧,因而只用一比特来编号就够了。

其发送方和接收方运行的流程图如图所示。

(3).后退n协议

由于停等协议要为每一个帧进行确认后才继续发送下一帧,大大降低了信道利用率,因此又提出了后退n协议。

后退n协议中,发送方在发完一个数据帧后,不停下来等待应答帧,而是连续发送若干个数据帧,即使在连续发送过程中收到了接收方发来的应答帧,也可以继续发送。

且发送方在每发送完一个数据帧时都要设置超时定时器。

只要在所设置的超时时间内仍收到确认帧,就要重发相应的数据帧。

如:

当发送方发送了N个帧后,若发现该N帧的前一个帧在计时器超时后仍未返回其确认信息,则该帧被判为出错或丢失,此时发送方就不得不重新发送出错帧及其后的N帧。

从这里不难看出,后退n协议一方面因连续发送数据帧而提高了效率,但另一方面,在重传时又必须把原来已正确传送过的数据帧进行重传(仅因这些数据帧之前有一个数据帧出了错),这种做法又使传送效率降低。

由此可见,若传输信道的传输质量很差因而误码率较大时,连续测协议不一定优于停止等待协议。

此协议中的发送窗口的大小为k,接收窗口仍是1。

(4).选择重传协议

在后退n协议中,接收方若发现错误帧就不再接收后续的帧,即使是正确到达的帧,这显然是一种浪费。

另一种效率更高的策略是当接收方发现某帧出错后,其后继续送来的正确的帧虽然不能立即递交给接收方的高层,但接收方仍可收下来,存放在一个缓冲区中,同时要求发送方重新传送出错的那一帧。

一旦收到重新传来的帧后,就可以原已存于缓冲区中的其余帧一并按正确的顺序递交高层。

这种方法称为选择重发(SELECTICEREPEAT),其工作过程如图所示。

显然,选择重发减少了浪费,但要求接收方有足够大的缓冲区空间。

三.实验代码以及代码说明:

实现代码如下:

#include"

sysinclude.h"

#include<

deque>

usingstd:

:

deque;

cout;

endl;

usingnamespacestd;

externvoidSendFRAMEPacket(unsignedchar*pData,unsignedintlen);

#defineWINDOW_SIZE_STOP_WAIT1

#defineWINDOW_SIZE_BACK_N_FRAME4/*themaxwindowssize*/

typedefenum{data,ack,nak}frame_kind;

/*definethestructureofframeandframehead*/

typedefstructframe_head{

frame_kindkind;

unsignedintseq;

unsignedintack;

unsignedchardata[100];

};

typedefstructframe{

frame_headhead;

unsignedintsize;

/*definethebufferzone*/

structStoreType{

frame*pfrm;

unsignedintsz;

deque<

StoreType>

mQue;

mQue2;

boolsendWinFull=false;

intcounter=0;

/*

*停等协议测试函数

*/

intstud_slide_window_stop_and_wait(char*pBuffer,intbufferSize,UINT8messageType)

{

unsignedintnum;

StoreTypes;

/*bythemessagetypetodecide*/

switch(messageType){

caseMSG_TYPE_TIMEOUT:

num=ntohl(*(unsignedint*)pBuffer);

s=mQue.front();

/*iftheseqisOK,sendit*/

if(num==((*s.pfrm).head.seq)){

SendFRAMEPacket((unsignedchar*)(s.pfrm),s.sz);

}

break;

caseMSG_TYPE_SEND:

/*prepareanewframe*/

s.pfrm=newframe;

(*s.pfrm)=*(frame*)pBuffer;

s.sz=bufferSize;

mQue.push_back(s);

/*sendallthedatainbuffer*/

if(!

sendWinFull){

s=mQue.front();

sendWinFull=true;

caseMSG_TYPE_RECEIVE:

/*receiveack*/

ack=ntohl(((frame*)pBuffer)->

head.ack);

if(mQue.size()!

=0){

if(ntohl(s.pfrm->

head.seq)==ack)/*receiverightackseqnumber*/

{

mQue.pop_front();

s=mQue.front();

SendFRAMEPacket(((unsignedchar*)s.pfrm),s.sz);

/*sendframesagain*/

}

}

else

{

sendWinFull=true;

/*databufferisempty*/

}

}

return0;

}

*回退n帧测试函数

intstud_slide_window_back_n_frame(char*pBuffer,intbufferSize,UINT8messageType)

intack;

intnum;

intj;

/*varusedinloopasnumber*/

intk;

/*nextistochoosefromthevars*/

switch(messageType)

{

caseMSG_TYPE_TIMEOUT:

/*datachange*/

for(j=0;

j<

mQue2.size()&

&

WINDOW_SIZE_BACK_N_FRAME;

j++)

{

s=mQue2[j];

if((*s.pfrm).head.seq==num)

break;

for(k=j;

k<

WINDOW_SIZE_BACK_N_FRAME&

mQue2.size();

k++){

s=mQue2[k];

/*resendframes*/

caseMSG_TYPE_SEND:

mQue2.push_back(s);

if(counter<

4)

s=mQue2.back();

/*sendtheNframes*/

counter++;

/*startthecounter*/

caseMSIG_TYPE_RECEVE:

ack=((frame*)pBuffer)->

head.ack;

/*receivecorrectack*/

j++)

if(ack==(*s.pfrm).head.seq)

if(j<

WINDOW_SIZE_BACK_N_FRAME)

for(k=0;

=j;

k++)

mQue2.pop_front();

counter--;

/*resetcuounter*/

k=counter;

for(;

counter<

4;

/*continuesendframes*/

*选择性重传测试函数

intstud_slide_window_choice_frame_resend(char*pBuffer,intbufferSize,UINT8messageType)

在实现1比特协议中,利用函数参数messageType传递的参数MSG_TYPE_TIMEOUT,MSG_TYPE_SEND和MSG_TYPE_RECEIVE,因此在函数主体中用switch进行分类,对应不同参数下的函数响应。

首先定义帧头、帧的结构,定义一个缓冲区,然后利用缓冲区的数据组装帧并调用发送函数发送组好的帧。

然后利用返回的MessageType参数实现分类。

在收到超时选项时,重新发送该帧(帧序号是ack),如果收到系统要发送帧,直接对缓冲区的帧进行发送;

如果收到的是接受帧的确认号,先进行转换,然后对比看是否相同,如果相同并且缓冲区还没有空,继续发送,否则调用发送函数重发该帧。

在后退N帧函数中,实现的窗口大小设置为WINDOW_SIZE_BACK_N_FRAME4,主体实现框架同一比特滑动窗口,只是多了两个计数器,分别用来记录发出的帧的seq和收到的ack。

在switch语句中,对于MessageType传递的参数来作出相应的响应:

①当传回的参数为超时时,先调用ntohl函数进行数据转换,再利用超时的帧号与窗口大小找到相应要重传的帧(最大帧号不超过窗口大小);

然后开始使用for循环依次发送这些帧。

②传回的参数为要发送帧时,取缓冲区的数据构建新帧,然后把构建的帧缓存,启动计数器counter,开始发送帧,每发送一个帧,counter累加(不能超过窗口大小)。

③参数为收到帧确认时,如果每一个ack号都是已经发送的帧头(在缓冲区里)的seq(ack=((frame*)pBuffer)->

head.ack)相同,继续发送下一组帧。

发送下一组帧之前先重新编排帧号,counter也相应重新编排。

在队列里如果序号k小于窗口大小并且counter小于4,用队列mQue2里的s开始继续发送帧。

4.总结:

整体来说,滑动窗口在实验中是固定的,这样便于处理帧号和ack的确认以及存储。

由于实验中实现的后退N帧还是利用了messageType参数,在未收到确认帧的时候只能选择重发滑动窗口中的帧,在帧完全确认接收正确以后才能发送新帧,这样实际运行起来效率会比较低(系统必须等待对方的确认)。

5.参考文献:

1.《计算机网络》(第5版)——电子工业出版社谢希仁编著

2.计算机网络(第4版)/世界著名计算机教材精选——清华大学出版社(美)特南鲍姆(Tanenbaum,A.S.)著,潘爱民译

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1