滑动窗口协议实验报告.docx
- 文档编号:3940382
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:10
- 大小:20.10KB
滑动窗口协议实验报告.docx
《滑动窗口协议实验报告.docx》由会员分享,可在线阅读,更多相关《滑动窗口协议实验报告.docx(10页珍藏版)》请在冰豆网上搜索。
滑动窗口协议实验报告
滑动窗口协议实验报告
篇一:
Exp1_滑动窗口协议_实验报告
Exp1滑动窗口协议实验报告
【实验目标】
?
理解和掌握“滑动窗口”技术。
?
基于计算机网络实验系统NetRiver进行。
?
NetRiver系统提供了各实验的上下文和接口函数,利用C/C++编程语言
实现典型协议的核心部分。
?
使用NetRiver系统完成程序代码的编译、调试和测试,验证协议实现的
正确性。
【实验原理】
1-bit滑动窗口协议
1-bit滑动窗口协议中,需要保证发送窗口大小不超过1。
我们用ack_expected表示发送窗口下界,即希望得到确认的帧号;用window_size表示当前发送窗口的大小。
当有事件到达时,根据事件的类型进行相应处理:
?
超时事件:
此时pBuffer指向的UINT32类型存储的是主机序的序列号seq,
将seq与当前窗口区间[ack_expected,ack_expected+windoe_size)进行比较,从seq开始连续进行发送。
?
网络层发送事件:
此时网络层想要发送一个新帧,pBuffer指向的是网络
层准备好的帧,我们将该帧放入缓冲队列,并在发送窗口未满时进行1次发送。
?
帧到达事件:
此时我们收到了一个帧,通过ntohl将其确认号转化成主
机序ack,然后对比ack是否等于ack_expected,若是则发送窗口下界加1,此时若还有帧在缓冲区则尝试进行1次发送,发送窗口上界加1。
回退n帧滑动窗口协议
回退n帧滑动窗口协议和1-bit滑动窗口协议相比,主要的区别在于窗口大小的不同,以及处理超时事件时,应从超时的帧开始进行连续发送。
其他事件的处理则没有不同。
【实验中遇到的问题】
起始编号
实验中帧号从1开始编号,而不是通常认为的0。
静态变量
由于两个函数将被分别连续调用,故不适合使用全局变量,否则将出现未初始化的现象。
这里我使用了函数内的静态变量来保证合适的初始值。
实验系统不稳定
实验过程中挺经常遇到服务器超时的现象,而且有时同一个程序运行两次也会有不同的结果。
一个经验性的做法是在程序中增加一些cout语句,实践上能够保证结果正确,但具体原因尚不清楚。
【源代码】
#include"sysinclude.h"#includeusingnamespacestd;
externvoidSendFRAMEPacket(unsignedchar*pData,unsignedintlen);
#defineWINDOW_SIZE_STOP_WAIT1#defineWINDOW_SIZE_BACK_N_FRAME4
//帧类型
typedefenum{data,ack,nak}frame_kind;//帧头
typedefstructframe_head{};//完整帧
typedefstructframe{};
//队列元素
typedefstructstore_elm{};/*
*停等协议测试函数
frame
*pframe;len;
//帧头//数据长度
frame_headunsignedint
head;size;
//帧头//数据的大小
frame_kindunsignedintunsignedintunsignedchar
kind;seq;ack;
//帧类型//序号//确认号//数据
data[100];
unsignedint
intstud_slide_window_stop_and_wait(char*pBuffer,intbufferSize,UINT8messageType){
switch(messageType){caseMSG_TYPE_TIMEOUT:
seq=*((UINT32*)pBuffer);
//给出主机序
//发送缓冲区
staticdequebuffDeque;staticUINT32window_size=0;staticUINT32ack_expected=1;UINT32seq,ack;store_elms;
//起始编号为1
if(ack_expected for(UINT32i=seq-ack_expected;i SendFRAMEPacket((unsignedchar
*)(buffDeque[i].pframe),buffDeque[i].len);
}break;
caseMSG_TYPE_SEND:
s.pframe=newframe;
//缓存新帧
*s.pframe=*(frame*)pBuffer;s.len=bufferSize;buffDeque.push_back(s);
if(window_size s=buffDeque[window_size++];
SendFRAMEPacket((unsignedchar*)(s.pframe),s.len);
//尝试发送
caseMSG_TYPE_RECEIVE:
ack=ntohl(((frame*)pBuffer)->head.ack);
ack_expected=ntohl(buffDeque[0].pframe->head.seq);if(ack==ack_expected){
buffDeque.pop_front();--window_size;++ack_expected;
if(buffDeque.size()>0&&window_size s=buffDeque[window_size++];
SendFRAMEPacket((unsignedchar*)(s.pframe),
//如果是等待的帧
WINDOW_SIZE_STOP_WAIT){
s.len);
}break;
}
}/*
}
return0;
break;
*回退n帧测试函数*/
intstud_slide_window_back_n_frame(char*pBuffer,intbufferSize,UINT8messageType){
switch(messageType){caseMSG_TYPE_TIMEOUT:
seq=*((UINT32*)pBuffer);
//给出主机序
cout staticdequebuffDeque;staticUINT32window_size=0;staticUINT32ack_expected=1;UINT32seq,ack;store_elms;
//起始编号为1
if(ack_expected for(UINT32i=seq-ack_expected;i SendFRAMEPacket((unsignedchar
*)(buffDeque[i].pframe),buffDeque[i].len);
}break;
caseMSG_TYPE_SEND:
s.pframe=newframe;
//缓存新帧
*s.pframe=*(frame*)pBuffer;s.len=bufferSize;buffDeque.push_back(s);
if(window_size s=buffDeque[window_size++];
SendFRAMEPacket((unsignedchar*)(s.pframe),s.len);
//尝试发送
caseMSG_TYPE_RECEIVE:
ack=ntohl(((frame*)pBuffer)->head.ack);
ack_expected=ntohl(buffDeque[0].pframe->head.seq);while(ack>=ack_expected){
buffDeque.pop_front();
//如果是等待的帧
++ack_expected;
if(buffDeque.size()>0&&window_size //尝试发送
s=buffDeque[window_size++];
SendFRAMEPacket((unsignedchar*)(s.pframe),
WINDOW_SIZE_BACK_N_FRAME){
s.len);}
}
break;
caseMSG_TYPE_RESEND:
seq=*((UINT32*)pBuffer);
default:
break;
}
return0;
}
//给出主机序
篇二:
滑动窗口实验报告
滑动窗口实验报告(含源码)
一、实验目的
1.实现一个数据链路层协议的数据传送部分。
2.更好地理解数据链路层协议中的“滑动窗口”技术的基本工作原理。
3.掌握计算机网络协议的基本实现技术。
二、实验要求
在一个数据链路层的模拟实现环境中,用C语言实现下两个数据链路层协议。
1.1比特滑动窗口协议
2.回退N帧滑动窗口协议
三、实验内容
充分理解滑动窗口协议,根据滑动窗口协议,模拟滑动窗口协议中发送端的功能,对系统发送的帧进行缓存并加入窗口等待确认,并在超时或者错误时对部分帧进行重传。
编写停等及退回N滑动窗口协议函数,响应系统的发送请求、接收帧消息以及超时消息,并根据滑动窗口协议进行相应处理。
四、源代码及注释
#include"sysinclude.h"
#include
usingnamespacestd;
externvoidSendFRAMEPacket(unsignedchar*pData,unsignedintlen);//1比特滑动窗口
#defineWINDOW_SIZE_STOP_WAIT1
//回退N帧协议
#defineWINDOW_SIZE_BACK_N_FRAME4
//缓存区大小
#defineBUFFER_SIZE50
typedefenum{DATA,ACK,NAK}Frame_kind;
//帧头
typedefstructFrame_head
{
Frame_kindkind;
unsignedintseq;
unsignedintack;
unsignedchardata[100];
};
//帧
typedefstructFrame
{
Frame_headhead;
unsignedintsize;
};
//缓存区
Framebuffer[BUFFER_SIZE];
//当前希望确认的帧,最近缓存的帧,下一次要发送的帧
unsignedintexpect_frame=0,last_buffered_frame=0,next_frame=0;
/*
*停等协议测试函数
*/
intstud_slide_window_stop_and_wait(char*pBuffer,intbufferSize,UINT8
messageType)
{
Frame_head*p=(Frame_head*)pBuffer;
//unsignedintframeNum=ntohl(*(unsignedint*)pBuffer);
switch(messageType)
{
//网络层要发送一帧数据时
caseMSG_TYPE_SEND:
{
//缓存当前要发送的帧
buffer[last_buffered_frame%BUFFER_SIZE].head=*p;
buffer[last_buffered_frame%BUFFER_SIZE].size=bufferSize;
//更新下次缓存的位置
++last_buffered_frame;
//如果当前有空闲的窗口可以用
if(last_buffered_frame-expect_frame //发送缓存帧
SendFRAMEPacket((unsignedchar*)pBuffer,(unsigned
int)bufferSize);
//窗口上界加1
++next_frame;
}
return0;
}
//物理层收到一帧数据时
caseMSG_TYPE_RECEIVE:
{
//解码确认信号
unsignedintack=ntohl(p->ack);
//试探
for(inti=expect_frame;i {
unsignedintexp_ack=ntohl(buffer[i%BUFFER_SIZE].head.seq);//如果确认消息大于等于期望消息,则说明期望帧已经被确认过了
if(ack>=exp_ack)
{
//期望帧+1
++expect_frame;
//如果有缓存帧没发出
if(next_frame {
//发出一个缓存帧
SendFRAMEPacket((unsignedchar*)(&buffer[next_frame%BUFFER_SIZE]),buffer[next_frame%BUFFER_SIZE].size);
//窗口上界+1
++next_frame;
}
//否则,无法继续发送帧,退出。
等待下次再更新期望确认帧elsebreak;
}
}
return0;
}
//超时
caseMSG_TYPE_TIMEOUT:
{
//超时重发,把当前窗口内未确认的帧重发一遍
for(inti=expect_frame;i {
//if(frameNum>ntohl(buffer[i%BUFFER_SIZE].head.seq))continue;SendFRAMEPacket((unsignedchar*)(&buffer[i%BUFFER_SIZE]),buffer[i%BUFFER_SIZE].size);
}
return0;
}
default:
break;
}
return-1;
}
/*
*回退n帧测试函数
*/
intstud_slide_window_back_n_frame(char*pBuffer,intbufferSize,UINT8
messageType)
{
Frame_head*p=(Frame_head*)pBuffer;
unsignedinttimeoutNum=*(unsignedint*)pBuffer;
switch(messageType)
{
//网络层要发送一帧数据时
caseMSG_TYPE_SEND:
{
buffer[last_buffered_frame%BUFFER_SIZE].head=*p;
buffer[last_buffered_frame%BUFFER_SIZE].size=bufferSize;
++last_buffered_frame;
//窗口数未达上限,则发送当前缓存帧,更新窗口上界
if(last_buffered_fr(转自:
小草范文网:
滑动窗口协议实验报告)ame-expect_frame WINDOW_SIZE_BACK_N_FRAME)
{
SendFRAMEPacket((unsignedchar*)z,(unsignedint)bufferSize);++next_frame;
}
return0;
}
//物理层接收到一帧数据时
caseMSG_TYPE_RECEIVE:
{
unsignedintack=ntohl(p->ack);
cout for(inti=expect_frame;i {
unsignedintexp_ack=ntohl(buffer[i%BUFFER_SIZE].head.seq);cout if(ack>=exp_ack)
{
++expect_frame;
if(next_frame {
SendFRAMEPacket((unsignedchar*)(&buffer[next_frame%BUFFER_SIZE]),buffer[next_frame%BUFFER_SIZE].size);
++next_frame;
}
}
elsebreak;
}
return0;
}
//超时
caseMSG_TYPE_TIMEOUT:
{
cout //超时重发
for(inti=expect_frame;i {
unsignedintframeNum=ntohl(buffer[i%BUFFER_SIZE].head.seq);//if(timeoutNum>frameNum)continue;
cout SendFRAMEPacket((unsignedchar*)(&buffer[i%BUFFER_SIZE]),buffer[i%BUFFER_SIZE].size);
}
return0;
}
default:
break;
}
return-1;
}
/*
*选择性重传测试函数
*/
intstud_slide_window_choice_frame_resend(char*pBuffer,intbufferSize,UINT8messageType)
{
return0;
}
五、思考题
1.退回N帧协议不必像1bit滑动窗口协议一样,允许发送完一
篇三:
实验一滑动窗口协议实验
实验一滑动窗口协议实验
?
实验目的:
在NetRiver实验系统中,用C语言实现滑动窗口协议中的1比特滑动窗口协议和后退N帧协议,理解滑动窗口协议
?
实验原理和说明:
(1).窗口机制
滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。
发送窗口和接收窗口的序号的上下界不一定要一样,甚至大小也可以不同。
不同的滑动窗口协议窗口大小一般不同。
发送方窗口内的序列号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧。
下面举一个例子(假设发送窗口尺寸为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协议中,接收方若发现错误帧就不再接收后续的帧,即使是正
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 滑动 窗口 协议 实验 报告