滑动窗口协议模拟程序的设计与实现.docx
- 文档编号:6211607
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:23
- 大小:281.24KB
滑动窗口协议模拟程序的设计与实现.docx
《滑动窗口协议模拟程序的设计与实现.docx》由会员分享,可在线阅读,更多相关《滑动窗口协议模拟程序的设计与实现.docx(23页珍藏版)》请在冰豆网上搜索。
滑动窗口协议模拟程序的设计与实现
长沙理工大学
《网络协议编程》课程设计报告
梁碧莹
学院计算机与通信工程专业网络工程
班级网络08-02学号************
学生姓名梁碧莹指导教师王静
课程成绩完成日期2011年7月2日
课程设计任务书
计算机与通信工程学院网络工程专业
课程名称
网络协议编程
课程设计
时间
2010~2011学年第二学期18~19周
学生姓名
梁碧莹
指导老师
王静
题目
滑动窗口协议模拟程序的设计与实现
主要内容:
(1)了解网络协议编程的基本知识;
(2)了解滑动窗口协议的工作机制;
(3)使用编程语言编写一个滑动窗口协议的模拟程序,按要求实现程序。
要求:
(1)按要求编写课程设计报告书,能正确阐述设计结果。
(2)通过课程设计培养学生严谨的科学态度,认真的工作作风和团队协作精神。
(3)学会文献检索的基本方法和综合运用文献能力。
(4)在老师的指导下,要求每个学生独立完成课程设计的全部内容。
应当提交的文件:
(1)课程设计报告。
(2)课程设计附件(源程序、各类图纸、实验数据、运行截图等)。
课程设计成绩评定
学院计算机通信工程专业网络工程
班级网络08-02班学号************
学生姓名梁碧莹指导教师王静
课程成绩完成日期2011年7月2日
指导教师对学生在课程设计中的评价
评分项目
优
良
中
及格
不及格
课程设计中的创造性成果
学生掌握课程内容的程度
课程设计完成情况
课程设计动手能力
文字表达
学习态度
规范要求
课程设计论文的质量
指导教师对课程设计的评定意见
综合成绩指导教师签字年月日
滑动窗口协议模拟程序的设计与实现
学生:
梁碧莹指导老师:
王静
摘要:
本文主要介绍如何根据滑动窗口协议的原理,在VisualC++的平台上设计一个滑动窗口协议模拟程序,并最终使该程序得以实现。
本次程序设计分两部分:
第一部分是发送方,第二部分是接收方。
通过发送方和接收方之间的数据帧传输模拟,学习滑动窗口协议控制流量的原理和方法,以及滑动窗口协议的工作机制。
关键词:
滑动窗口协议流量控制工作机制模拟程序
DesignandImplementationof SlidingWindow Protocol Procedures
Student:
LiangBiyingInstructor:
WangJing
Abstract:
ThispaperdescribestheprincipleofSlidingWindow ProtocolandhowtodesignandimplementaprocedureabouttheSlidingWindow Protocol.The programdesign intwoparts,oneis thesender, theotheris thereceiver.Afterall,studyingtheprincipleandmethodofhowtheSlidingWindow Protocolcontroltheflow,andhowtheSlidingWindow Protocolworksthroughthetransmissionofdatabetweenthesenderandthereceiver.
Keywords:
SlidingwindowprotocolFlowcontrolWorkingmechanismSimulationprogram
1引言
随着网络的不断壮大,用户数量、信息量的需求不断增加,网络负荷越来越重。
此时,我们迫切需要一种机制来控制网络的流量,减少网络拥堵的几率,提高传输的效率。
因此,一种名为滑动窗口的协议应运而生。
滑动窗口协议,是TCP使用的一种流量控制方法。
该协议允许发送方在停止并等待确认前可以连续发送多个分组。
由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。
经测试证明,该协议还能有效地解决TCP的高协议处理开销和UDP的低可靠性之间的矛盾,
1.1滑动窗口协议概述
滑动窗口协议,是TCP使用的一种流量控制方法。
滑动窗口协议也称为Go-Back-N(GBN)协议。
在该协议中,允许发送方传输多个分组(当有多个分组时)而不需等待确认,但它也受限于在流水账中未确认的分组数不能超过最大允许数N。
只有在接收窗口向前滑动时(与此同时也发送了确认),发送窗口才有可能向前滑动。
收发两端的窗口按照以上规律不断地向前滑动,因此这种协议又称为滑动窗口协议。
当发送窗口和接收窗口的大小都等于1时,就是停止等待协议。
当发送窗口大于1,接收窗口等于1时,就是回退N步协议。
当发送窗口和接收窗口的大小均大于1时,就是选择重发协议。
协议中规定,对于窗口内未经确认的分组需要重传。
这种分组的数量最多可以等于发送窗口的大小,即滑动窗口的大小n减去1(因为发送窗口不可能大于(n-1),起码接收窗口要大于等于1)。
1.2本次设计任务
本次的设计任务是根据滑动窗口协议的工作原理,在VisualC++6.0的平台上用C++语言编写一个基于TCP滑动窗口协议的模拟程序。
要求该程序能够实现滑动窗口协议的发送和接收数据帧功能,在此功能上体现滑动窗口协议的运作,如:
发送帧被接收与否的判断,帧超时重发,帧缓存等。
2滑动窗口协议介绍
2.1滑动窗口协议工作原理
TCP协议在工作时,如果发送端的TCP协议软件每传输一个数据分组后,必须等待接收端的确认才能够发送下一个分组,由于网络传输的时延,将有大量时间被用于等待确认,导致传输效率低下。
为此TCP在进行数据传输时使用了滑动窗口机制。
TCP滑动窗口用来暂存两台计算机间要传送的数据分组。
每台运行TCP协议的计算机有两个滑动窗口:
一个用于数据发送,另一个用于数据接收。
发送端待发数据分组在缓冲区排队等待送出。
被滑动窗口框入的分组,是可以在未收到接收确认的情况下最多送出的部分。
滑动窗口左端标志X的分组,是已经被接收端确认收到的分组。
随着新的确认到来,窗口不断向右滑动。
TCP协议软件依靠滑动窗口机制解决传输效率和流量控制问题。
它可以在收到确认信息之前发送多个数据分组。
这种机制使得网络通信处于忙碌状态,提高了整个网络的吞吐率,它还解决了端到端的通信流量控制问题,允许接收端在拥有容纳足够数据的缓冲之前对传输进行限制。
在实际运行中,TCP滑动窗口的大小是可以随时调整的。
收发端TCP协议软件在进行分组确认通信时,还交换滑动窗口控制信息,使得双方滑动窗口大小可以根据需要动态变化,达到在提高数据传输效率的同时,防止拥塞的发生。
称窗口左边沿向右边沿靠近为窗口合拢,这种现象发生在数据被发送和确认时。
当窗口右边沿向右移动时将允许发送更多的数据,称之为窗口张开。
这种现象发生在另一端的接收进程读取已经确认的数据并释放了TCP的接收缓存时。
当右边沿向左移动时,称为窗口收缩。
HostRequirementsRFC强烈建议不要使用这种方式。
但TCP必须能够在某一端产生这种情况时进行处理。
如果左边沿到达右边沿,则称其为一个零窗口。
2.2滑动窗口算法
滑动窗口算法工作过程如下:
首先,发送方为每1帧赋一个序号(sequencenumber),记作SeqNum。
现在,我们忽略SeqNum是由有限大小的头部字段实现的事实,而假设它能无限增大。
发送方维护3个变量:
发送窗口大小(sendwindowsize),记作SWS,给出发送方能够发 送但未确认的帧数的上界; LAR表示最近收到的确认帧(lastacknowledgementreceived)的序号;LFS表示最近发送的帧(lastframesent)的序号,发送方还维持如下的不变式:
LAR-LFS≤SWS 。
图2-1滑动窗口算法的时间线
当一个确认到达时,发送方向右移动LAR,从而允许发送方发送另一帧。
同时,发送方为所发的每个帧设置一个定时器,如果定时器在ACK到达之前超时,则重发此帧。
注意:
发送方必须存储最多SWS个帧,因为在它们得到确认之前必须准备重发。
接收方维护下面3个变量:
接收窗口大小(receivewindowsize),记为RWS,给出接收方所能接收的无序帧数目的上界;LAF表示可接收帧(largestacceptableframe)的序号;LFR表示最近收到的帧(lastframereceived)的序号。
接收方也维持如下不变式:
LFS-LAR≤SWS
图2-2接收方的滑动窗口
当一个具有顺序号SeqNum的帧到达时,接收方采取如下行动:
如果SeqNum≤LFR或SeqNum>LAF,那么帧不在接收窗口内,于是被丢弃;如果LFR<SeqNum≤LAF,那么帧在接收窗口内,于是被接收。
现在接收方需要决定是否发送一个ACK。
设SeqNumToACK表示未被确认帧的最大序号,则序号小于或等于SeqNumToACK的帧都已收到。
即使已经收到更高序号的分组,接收方仍确认SeqNumToACK的接收。
这种确认被称为是累积的(cumulative)。
然后它设置LFA=SeqNumToACK,并调整LFA=LFR+RWS。
图2-3接收方的滑动窗口
窗口协议算法有三个功能:
●在不可靠链路上可靠地传输帧
●保持帧的传输顺序
●支持流量控制
3设计方案及分析
3.1窗口机制总体设计及分析
图3-1发送方和接收方状态示意图
设计分析:
(1)初始态,发送方没有帧发出,发送窗口前后沿相重合。
接收方0号窗口打
开,等待接收0号帧;
(2)发送方打开0号窗口,表示已发出0帧但尚未确认返回信息。
此时接收窗口状态不变;
(3)发送方打开0、1号窗口,表示0、1号帧均在等待确认之列。
至此,发送方打开的窗口数已达规定限度,在未收到新的确认返回帧之前,发送方将暂停发送新的数据帧。
接收窗口此时状态仍未变;
(4)接收方已收到0号帧,0号窗口关闭,1号窗口打开,表示准备接收1号帧。
此时发送窗口状态不变;
(5)发送方收到接收方发来的0号帧确认返回信息,关闭0号窗口,表示从重发表中删除0号帧。
此时接收窗口状态仍不变;
(6)发送方继续发送2号帧,2号窗口打开,表示2号帧也纳入待确认之列。
至此,发送方打开的窗口又已达规定限度,在未收到新的确认返回帧之前,发送方将暂停发送新的数据帧,此时接收窗口状态仍不变;
(7)接收方已收到1号帧,1号窗口关闭,2号窗口打开,表示准备接收2号帧。
此时发送窗口状态不变;
(8)发送方收到接收方发来的1号帧收毕的确认信息,关闭1号窗口,表示从重发表中删除1号帧。
此时接收窗口状态仍不变。
3.2协议选择及分析
在设计过程中,我主要运用了选择重传协议,该协议能很好地弥补了1比特滑动窗口协议和后退n协议的缺点,是比较完善的滑动窗口协议。
在选择重传协议中,当接收方发现某帧出错后,其后继续送来的正确的帧虽然不能立即递交给接收方的高层,但接收方仍可收下来,存放在一个缓冲区中,同时要求发送方重新传送出错的那一帧。
一旦收到重新传来的帧后,就可以原已存于缓冲区中的其余帧一并按正确的顺序递交高层。
这种方法称为选择重发(SELECTICEREPEAT),其工作过程如图所示。
显然,选择重发减少了浪费,但要求接收方有足够大的缓冲区空间。
图3-2选择重传协议原理图
3.3发送方与接收方设计流程
由于我设计的程序为模拟程序,因此我把发送方和接收方集合在同一版面上。
它们各自的功能同时在同一版面上实现及显示。
在程序实现后,我们可以通过在同一版面根据提示输入相关信息,即可得到模拟过程。
虽然只有一个版面,但是发送方和接收方的功能是清晰的、相对齐全的。
发送方和接收方的设计流程如下:
图3-3发送方与接收方设计流程
根据流程图的实现步骤,我编写了以下的代码。
(1)发送方程序:
本程序设有四个变量:
一是窗口大小变量,二是第一帧序列号变量,三是最近发送的帧变量,最后一个是最近收到的确认帧变量。
swpstate1.head=NULL;//变量初始值为空
swpstate1.sendq=sendq_rear=(structsendq_slot*)malloc(sizeof(structsendq_slot);
if(!
swpstate1.sendq)exit
(1);
sendq_rear->next=NULL;
printf("请输入窗口大小:
");
scanf("%ld",&swpstate1.sws);//输入窗口大小
swpstate1.rws=swpstate1.sws;//把窗口大小的值赋给变量
if(swpstate1.sws>0)
{
printf("请输入第一帧的序列号:
");
scanf("%ld",&swpstate1.hdr.seqnum);//输入第一帧序列号
}
swpstate1.nfe=swpstate1.hdr.seqnum;//把第一帧的值放进缓冲池内
sendp=(structsendq_slot*)malloc(sizeof(structsendq_slot));
if(!
sendp)exit
(1);
sendp->msg=swpstate1.hdr.seqnum;
sendp->timeout=1;
sendp->next=NULL;
sendq_rear->next=sendp;
sendq_rear=sendp;
--swpstate1.sws;
swpstate1.lfs=swpstate1.hdr.seqnum;//最近发送的帧取值
swpstate1.lar=swpstate1.hdr.seqnum;//最近收到的确认帧取值
do
{
while(swpstate1.sws>0)//当窗口大小大于0时,执行以下的循环
{
sendp=(structsendq_slot*)malloc(sizeof(structsendq_slot));
if(!
sendp)exit
(1);
sendp->msg=swpstate1.lfs+1;//如果输入的帧序号大于之前帧序号,那么窗口向前滑动
sendp->timeout=1;//时延为1
sendp->next=NULL;
sendq_rear->next=sendp;
sendq_rear=sendp;
--swpstate1.sws;
++swpstate1.lfs;
}
swpstate1.hdr.acknum=0;//ACK清空
swpstate1.hdr.flags=0;//存储缓冲池清空
printf("最近收到的ACK的帧序号:
%ld\n",swpstate1.lar);
//输出最近收到的ACK帧序号
printf("最近发送的帧序号(发送新帧后):
%ld\n",swpstate1.lfs);
//输出最近发送帧序号
(2)接收方程序:
图3-4数据包接收过程
●接收方的接收原则从总体上看是先判断输入的数据帧是否在接收范围之内,若是,则继续判断是否符合其他接收条件;若不是,则马上丢弃该数据帧,不再进行其他条件的判断。
structsendq_slot*sendq_rear,*sendp,*p3,*p4;//设定变量
structrecvq_slot*recvp,*recvq_rear,*p1,*p2;
if(swpstate1.hdr.flags==0)
//上次输入的数据帧被放置在缓存区,输入区被清空
{
do//如果继续接收数据帧则实施下面循环
{
printf("请输入收到的数据帧号:
");
scanf("%ld",&a);
if(a>=swpstate1.nfe&&a<=swpstate1.lfs)//判断数据帧应被接收或缓存
{
if(swpstate1.head==NULL)
{
recvp=recvq_rear=(structrecvq_slot*)malloc(sizeof(structrecvq_slot));
recvp->next=NULL;
swpstate1.head=recvp;
}
else
if(swpstate1.head!
=NULL)
{
recvp=(structrecvq_slot*)malloc(sizeof(structrecvq_slot));
recvp->next=NULL;
recvq_rear->next=recvp;
recvq_rear=recvp;
}
}
else
{
printf("所输数据不在接收窗口内!
");
break;//跳出该循环
}
●若输入数据帧在接收范围内则继续判断并进行以下循环。
recvp->msg=a;
if(recvp->msg==swpstate1.nfe)//是否放入缓存判断
recvp->received=1;
else
recvp->received=0;
--swpstate1.rws;
if(recvp->received==1)//数据帧被接收,则进行下面语句
{a=a-1;
do
{a=a+1;
if(swpstate1.head==NULL)
break;
p1=swpstate1.head;
flag=0;
while((a!
=p1->msg)&&(p1->next!
=NULL))
{
p2=p1;p1=p1->next;
}
if(a==p1->msg)
{
flag=1;
if(p1==swpstate1.head)
swpstate1.head=swpstate1.head->next;
elsep2->next=p1->next;
swpstate1.nfe=a+1;
swpstate1.hdr.acknum=a+1;
swpstate1.hdr.flags=1;
}
}while(flag==1);
}
printf("ACK号(期待的下一帧的序号):
%ld\n",swpstate1.nfe);
printf("没按序接受的序号:
\n");
p1=swpstate1.head;
while(p1!
=NULL)
{
printf("%ld\t",p1->msg);
p1=p1->next;
}
●当接收完一个数据帧时,我们可以选择终止下面的继续接收,也可以选择继续接收。
如果继续接收,那么程序跳到判断循环,继续判断是否接收下一个数据帧,原理与上面相当。
while((swpstate1.rws>0)&&(b==1));
if(swpstate1.hdr.flags==1)
{p3=swpstate1.sendq->next;
flag=0;
while((swpstate1.hdr.acknum)!
=p3->msg&&p3->next!
=NULL)
{p4=p3;p3=p3->next;}
if(swpstate1.hdr.acknum==p3->msg)
{
flag=1;
if(p3->msg==swpstate1.sendq->next->msg)
swpstate1.sendq->next=p3;
elseswpstate1.sendq->next=p3;
}
swpstate1.sws=swpstate1.sws+(swpstate1.sendq->next->msg-swpstate1.lar);
swpstate1.lar=swpstate1.sendq->next->msg;
swpstate1.hdr.seqnum=swpstate1.hdr.acknum;
printf("最近收到的ACK的帧序号(收到ACK后):
%ld\n",swpstate1.lar);
printf("最近发送的帧序号(此时还未发送新的数据):
%ld\n",swpstate1.lfs);
}
4程序测试
下面我以窗口大小为11,第一帧序列号为3,做程序的测试。
图4-1程序测试整体图
(1)整体窗口展示,命令行界面
图4-2整体窗口展示
(2)输入窗口大小及第一帧序列号
图4-3信息设置输入
(3)当输入的接收帧并不是ACK期待的帧,那么根据滑动窗口协议该帧不被接收,且把该帧存放在缓冲区。
图4-4帧不被接收的情况
(4)当前面输入的都不是系统所期待的帧,那么这些帧会一直被存放在缓冲区。
直到输入下一个输入的帧的序号比前面输入的帧的序号大,且是系统所期待的帧时,之前和当前输入的帧会一并被接收,缓冲区清空。
继续接收命令,进行新的帧的检测及接收。
图4-5帧被接收的情况
(5)若输入的帧超过了窗口大小,那么系统会显示该帧不在接收范围内,并拒绝接收。
图4-6帧超出窗口大小范围
5总结
5.1程序改进与完善
该滑动窗口协议模拟程序还有进一步完善的余地,例如可以对以下一些地方进行改进:
(1)改模拟程序通过命令行来实行,缺少形象直观的界面,希望日后可以设计比较简单明了的界面来展示程序的主要模拟功能。
(2)现在我们模拟的只是一些用序号代名的简单的帧,建议可以改善程序,使该系统可以模拟更接近真实的数据帧。
这样可以联系实际更直观地去验证滑动窗口协议。
(3)整体来说,滑动窗口在实验中是固定的,这样便于处理帧号和ack的确认以及存储。
但建议可以在日后改进使其变成动态的。
5.2设计总结
以上为我所设计的滑动窗口模拟程序,它经过多次修改和整理,已是一个比较不错的设计,可以基本实现所需功能,但因为水平有限,此程序中也存在一定的问题,这需要以后更进一步的改进。
参考文献
[1]谢希仁.计算机网络[M].4版.北京:
电子工业出版社,2003.
[2]李仁发,何彦.基于虚拟实验方法的滑动窗口协议分析[J].系统仿真学报,2002,8(14):
1026-1063.
[3]李建中,张冬冬.滑动窗口规模的动态调整算法[J].软件学报,2004,12(15):
1800-1814.
[4]王栩,李建中,王伟平.基于滑动窗口的数据流压缩技术及连续查询处理方法[J].计算机研究与发展,2004,10(41):
1639-1644.
[5
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 滑动 窗口 协议 模拟 程序 设计 实现