资源描述
计算机网络课程设计书
学 院
计算机与信息工程学院
专 业
网络工程
课程名称
计算机网络
题 目
滑动窗口协议仿真
完成期限
自2015年6月23日至2015年6月29日共1周
内
容
及
任
务
一、 项目的目的
掌握滑动窗口协议的工作原理,并能够用所学计算机高级语言进行编程模拟其运行过程;培养学生的动手实践和思考能力。
二,项目任务的主要内容和要求
(1)本次设计任务是根据滑动窗口协议的工作原理,在Visual C++ 6.0的平台上用C++语言编写一个基本TCP滑动窗口协议的模拟程序。
(2)要求该程序能够实现滑动窗口协议的发送和接收数据帧功能,在此功能上体现滑动窗口协议的运作。
(3) 程序按照滑动窗口协议实现端对端的数据传送。包括协议的各种策略,如包丢失、停等应答、超时等都应有所仿真实现;
(4) 显示数据传送过程中的各项具体数据。双方帧的个数变化,帧序号,发送和接受速度,暂停或重传提示等;
三、 项目设计(研究)思路
(1) 查阅相关资料,理解滑动窗口协议的工作原理;
(2) 设计滑动窗口协议实现端对端数据传送的功能流程图;
(3) 编写代码实现滑动窗口协议工作的模拟程序,包括包丢失、停等应答、超时等;
(4) 测试程序功能的实现情况。
四、 具体成果形式和要求
(1)滑动窗口协议实现端对端数据传送的模拟程序。
(2)按照要求撰写课程设计报告并准备答辩。
进
度
安
排
起止日期
工作内容
2015.6.23—2015。6。24
了解网络协议编程的基本知识;
2015。6。25-2015.6.26
了解滑动窗口协议的工作机制;
2015.6.27—2015.6.28
使用编程语言编写一个滑动窗口协议的模拟程序,按要求实现程序.
2015。6.29
最后汇总,调试,答辩
主
要
参
考
资
料
[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] 特南鲍姆. 计算机网络(第四版)。 清华出版社
指导教师
意见
(签字): ×年×月×日
系(教研室)主任意见
(签字): ×年×月×日
计算机网络课程设计说明书
(封面)
学院名称: 计算机与信息工程学院
班级名称: 网络工程一班
学生姓名:
学 号: 201321
题 目: 滑动窗口协议仿真
指导教师
姓 名: 邵雪梅
起止日期: 2015。6。23-2015。6。29
第一部分:正文部分
一,选题背景
早期的网络通信中,通信双方不会考虑网络的拥挤情况直接发送数据。由于大家不知道网络拥塞状况,一起发送数据,导致中间结点阻塞掉包,谁也发不了数据。在数据传输过程中,我们总是希望数据传输的更快一些,但如果发送方把数据发送的过快,接收方就可能来不及接收,这就造成数据的丢失。因此就有了滑动窗口机制来解决这些问题。早期我们使用的是1bit滑动窗口协议,一次只发送一个帧,等收到ack确认才发下一个帧,这样对信道的利用率太低了。因此提出了一种采用累积确认的连续ARQ协议,接收方不必对收到的帧逐个发送ack确认,而是收到几个帧后,对按序到达的最后一个帧发送ack确认。同1bit滑动窗口协议相比,大大减少了ack数量,并消除了延迟ack对传输效率的影响.但是,这会产生一个新的问题,如果发送方发送了5个帧,而中间的第3个帧丢失了。这时接收方只能对前2个帧发出确认.发送方无法知道后面三个帧的下落,只好把后面的3个帧再重传一次,这就是回退N协议。为了解决这个问题,又提出了选择重传协议。当接收方发现某帧出错后,继续接受后面送来的正确的帧,只是不交付它们,存放在自己的缓冲区中,并且要求发送方重传出错的那一帧。一旦收到重传来的帧后,就可以将存于缓冲区中的其余帧一并按正确的顺序递交给主机。本文主要介绍如何根据滑动窗口协议的原理,在Visual C++的平台上设计一个滑动窗口协议模拟程序,并最终使该程序得以实现。本次程序设计分两部分:第一部分是发送方,第二部分是接收方。通过发送方和接收方之间的数据帧传输模拟,学习滑动窗口协议控制流量的原理和方法,以及滑动窗口协议的工作机制。
二、设计理念
2.1 滑动窗口协议工作原理
TCP滑动窗口用来暂存两台计算机间要传送的数据分组。每台运行TCP协议的计算机有两个滑动窗口:一个用于数据发送,另一个用于数据接收。发送端待发数据分组在缓冲区排队等待送出。被滑动窗口框入的分组,是可以在未收到接收确认的情况下最多送出的部分。滑动窗口左端标志X的分组,是已经被接收端确认收到的分组.随着新的确认到来,窗口不断向右滑动。
滑动窗口算法工作过程如下:
首先,发送方为每1帧赋一个序号(sequence number),记作SeqNum。现在,我们忽略SeqNum是由有限大小的头部字段实现的事实,而假设它能无限增大.发送方维护3个变量:发送窗口大小(send window size),记作SWS,给出发送方能够发送但未确认的帧数的上界; LAR表示最近收到的确认帧(last acknowledgement received)的序号;LFS表示最近发送的帧(last frame sent)的序号,发送方还维持如下的不变式:LAR-LFS≤SWS .
2—1滑动窗口协议工作图
窗口协议算法有三个功能:
l 在不可靠链路上可靠地传输帧
l 保持帧的传输顺序
l 支持流量控制
2.2 选择重传协议
在选择重传协议中,当接收方发现某帧出错后,其后继续送来的正确的帧虽然不能立即递交给接收方的高层,但接收方仍可收下来,存放在一个缓冲区中,同时要求发送方重新传送出错的那一帧。一旦收到重新传来的帧后,就可以原已存于缓冲区中的其余帧一并按正确的顺序递交高层。这种方法称为选择重发(SELECTICE REPEAT),其工作过程如图所示。显然,选择重发减少了浪费,但要求接收方有足够大的缓冲区空间.
2—2 选择重传协议原理图
三、过程论述
(1)发送方程序流程图:
3—1发送方程序流程图
(2)接收方程序流程图:
收到的包是否含有Push标志?
收到包的序号与等待接收的序号是否一致?
收到包的序号在接收窗口范围内?
N
Y
直接提取数据,
提前应用进程
Y
入接收队列
Y
N
处理在接收队列中的包(如果是普通包要判断序号,或者进行拆包,组包操作)
结束
N
3—2接受方程序流程图
3。2 功能实现
(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=(struct sendq_slot*) malloc (size of(struct sendq_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=(struct sendq_slot*)malloc(sizeof(struct sendq_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)接收方的接收原则从总体上看是先判断输入的数据帧是否在接收范围之内,若是,则继续判断是否符合其他接收条件;若不是,则马上丢弃该数据帧,不再进行其他条件的判断。
struct sendq_slot *sendq_rear,*sendp,*p3,*p4; //设定变量
struct recvq_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=(struct recvq_slot*)malloc(sizeof(struct recvq_slot));
recvp->next=NULL;
recvq_rear—〉next=recvp;
recvq_rear=recvp;
}
}
else
{
printf(”所输数据不在接收窗口内!");
break; //跳出该循环
}
(3)若输入数据帧在接收范围内则继续判断并进行以下循环。
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;
else p2-〉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;
}
(4)当接收完一个数据帧时,我们可以选择终止下面的继续接收,也可以选择继续接收。如果继续接收,那么程序跳到判断循环,继续判断是否接收下一个数据帧,原理与上面相当。
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;
else swpstate1.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);
}
四、结果分析
滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。发送窗口和接收窗口的序号的上下界不一定要一样,甚至大小也可以不同。不同的滑动窗口协议窗口大小一般不同。发送方窗口内的序号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧。接受方为其窗口内的每一个序号保留了一个缓冲区。与每个缓冲区相关联的还有一位,用来指明该缓冲区是满的还是空的.
若从滑动窗口的观点来统一看待1比特滑动窗口、后退n及选择重传三种协议,它们的差别仅在于各自窗口尺寸的大小不同而已.1比特滑动窗口协议:发送窗口=1,接收窗口=1;后退N协议:发送窗口>1,接收窗口=1;选择重传协议:发送窗口〉1,接收窗口>
五、结论(或总结)
下面我以窗口大小为11,第一帧序列号为3,做程序的测试
图5 测试结果
(1)整体窗口展示,命令行界面
5—1图
(2)输入窗口大小及第一帧序列号
5—2图
(3)当输入的接收帧并不是ACK期待的帧,那么根据滑动窗口协议该帧不被接收,且把该帧存放在缓冲区.
5—3图
(4)若输入的帧超过了窗口大小,那么系统会显示该帧不在接收范围内,并拒绝接收。
5-4图
5-5图
6总结
6。1程序改进与完善
该滑动窗口协议模拟程序还有进一步完善的余地,例如可以对以下一些地方 进行改进:
(1)改模拟程序通过命令行来实行,缺少形象直观的界面,希望日后可以设计 比较简单明了的界面来展示程序的主要模拟功能。
(2)现在我们模拟的只是一些用序号代名的简单的帧,建议可以改善程序,使 该系统可以模拟更接近真实的数据帧.这样可以联系实际更直观地去验证滑动窗口协议。
(3)整体来说,滑动窗口在实验中是固定的,这样便于处理帧号和ack的确认 以及存储.但建议可以在日后改进使其变成动态的。
6.2设计总结
以上为我所设计的滑动窗口模拟程序,它经过多次修改和整理,已是一个比较不错的设计,可以基本实现所需功能,但因为水平有限,此程序中也存在一定的问题,这需要以后更进一步的改进
第二部分:参考文献
[1] Andrew S。 Tandenbaum. Computer Networks(3rdEDITION)[M] . Prentice Hall 。1996.
[3] 谢希仁 编著《计算机网络》(第5版)—-电子工业出版社
[4] 陈洛资。 计算机网络软件设计、开发与编程[M] 。北京:科学出版社。 1994.
[5] 高传善。 计算机网络教程[M] 。 上海:复旦大学出版社。 1996.
[6] 谢希仁. 计算机网络[M]. 4版. 北京:电子工业出版社, 2003。
[7] 李仁发。何彦.基于虚拟实验方法的滑动窗口协议分析[J]. 系统仿真学报。 2002. 8 (14) : 1026 — 1063.
学生签名 填表日期 年 月 日
第三部分: 指导教师评语
第四部分:成绩评定
指导教师签名: 填表日期: 年 月 日
展开阅读全文