滑动窗口的仿真协议书范本
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机网络课程设计书
计算机网络课程设计说明书
(封面)
学院名称:计算机与信息工程学院
班级名称:网络工程一班
学生姓名:
学号:201321
题目滑动窗口协议仿真指导教师
姓名:邵雪梅
起止日期:2015.6.23 —2015629
第一部分:正文部分
一,选题背景
早期的网络通信中,通信双方不会考虑网络的拥挤情况直接发送数据。由于大家不知道网络拥塞状况,一起发送数据,导致中间结点阻塞掉包,谁也发不了数
据。在数据传输过程中,我们总是希望数据传输的更快一些,但如果发送方把数据发送的过快,接收方就可能来不及接收,这就造成数据的丢失。因此就有了滑动窗口机制来解决这些问题。早期我们使用的是1bit滑动窗口协议,一次只发送一个帧,等收到ack确认才发下一个帧,这样对信道的利用率太低了。因此提出了一种采用累积确认的连续ARQ协议,接收方不必对收到的帧逐个发送ack确认,而是收到几个帧后,对按序到达的最后一个帧发送ack确认。
同1bit滑动窗口协议相比,大大减少了ack数量,并消除了延迟ack对传输效率的影响。但是,这会产生一个新的问题,如果发送方发送了5个
帧,而中间的第3个帧丢失了。这时接收方只能对前2个帧发出确认。发送方无
法知道后面三个帧的下落,只好把后面的3个帧再重传一次,这就是回退N协
议。为了解决这个问题,又提出了选择重传协议。当接收方发现某帧出错后,继续接受后面送来的正确的帧,只是不交付它们,存放在自己的缓冲区中,并且要求发送方重传出错的那一帧。一旦收到重传来的帧后,就可以将存于缓冲区中的其余帧一并按正确的顺序递交给主机。本文主要介绍如何根据滑动窗口协议的原理,在Visual C++ 的平台上设计一个滑动窗口协议模拟程序,并最终使该程序得以实
现。本
次程序设计分两部分:第一部分是发送方,第二部分是接收方。通过发送方和接
收方之间的数据帧传输模拟,学习滑动窗口协议控制流量的原理和方法,以及滑动窗口协议的工作机制。
、设计理念
2.1 滑动窗口协议工作原理
TCP骨动窗口用来暂存两台计算机间要传送的数据分组。每台运行TCP协议的计算机有两个滑动窗口:一个用于数据发送,另一个用于数据接收。发送端待发数据分组在缓冲区排队等待送出。被滑动窗口框入的分组,是可以在未收到接收确认的情况下最多送出的部分。滑动窗口左端标志X的分组,是已经被接收端确认收到的分组。随着新的确认到来,窗口不断向右滑动。
滑动窗口算法工作过程如下:
首先,发送方为每1帧赋一个序号(seque nee number),记作SeqNum现在,我们忽略SeqNun是由有限大小的头部字段实现的事实,而假设它能无限增大。发送方维护3个变量:发送窗口大小(send window size ),记作SWS给出发送方能够发送但未确认的帧数的上界;LAR表示最近收到的确认帧(last
ack no wledgeme nt received )的序号;LFS 表示最近发送的帧 (last frame se nt) 的序号,发送方还维持如下的不变式:LAR-LFSC SWS。
2-1滑动窗口协议工作图窗口协议算法有三个功
能:
在不可靠链路上可靠地传输帧保持帧的传输顺序支持流量控制
2.2选择重传协议
在选择重传协议中,当接收方发现某帧出错后,其后继续送来的正确的帧虽 然不能立即递交给接收方的高层,但接收方仍可收下来,存放在一个缓冲区中, 同时要求发送方重新传送出错的那一帧。一旦收到重新传来的帧后,就可以原已 存于缓冲区中的其余帧一并按正确的顺序递交高层。这种方法称为选择重发 (SELECTICEREPEAT )其工作过程如图所示。显然,选择重发减少了浪费,但要 求接收方有足够大的缓冲区空间。
2-2选择重传协议原理图
三、过程论述
(1 )发送方程序流程图:
对
譎
0T 葡诗幢
一发诡祯蟹遇挣1S
3-1发送方程序流程图
(2)接收方程序流程图:
3-2接受方程序流程图
3.2功能实现
(1)发送方程序:
本程序设有四个变量:一是窗口大小变量,二是第一帧序列号变量,三是最
近发送的帧变量,最后一个是最近收到的确认帧变量
swpstate1.head=NULL; // 变量初始值为空
swpstate1.se ndq=se ndq_rear=(structse ndq_slot*)malloc(sizeof(structse n dq_slot); if(!swpstate1.sendq) exit(1);
sen dq_rear- >n ext=NULL;
prin tf(" 请输入窗口大小:");
sca nf("%ld",&swpstate1.sws); // 输入窗口大小
swpstate1.rws=swpstate1.sws; // 把窗口大小的值赋给变量
if (swpstate1.sws>0)
{
prin tf(" 请输入第一帧的序列号:");
sca nf("%ld",&swpstate1.hdr.se qn um); // 输入第一帧序列号
}
swpstate1. nfe=swpstate1.hdr.se qn um; // 把第一帧的值放进缓冲池内
sen dp=(struct sen dq_slot*) malloc (size of(struct sen dq_slot));
if(!se ndp) exit(1);
sen dp->msg=swpstate1.hdr.se qnum;
sen dp->timeout=1;
sen dp->n ext=NULL;
sen dq_rear- >n ext=se ndp;
sen dq_rear=se ndp;
--swpstate1.sws;
swpstate1 .l fs=swpstate1.hdr.se qnum; // 最近发送的帧取值
swpstate1 .l ar=swpstate1.hdr.se qnum; // 最近收至U的确认帧取值
do
{
while(swpstate1.sws>0) // 当窗口大小大于0时,执行以下的循环
{
sen dp=(struct sen dq_slot*)malloc(sizeof(struct sen dq_slot));
if(!se ndp) exit(1);
sen dp->msg=swpstate1.lfs+1; // 如果输入的帧序号大于之前帧序
号,那么窗口向前滑动
sen dp->timeout=1; // 时延为1
sen dp->n ext=NULL;
sen dq_rear- >n ext=se ndp;
sen dq_rear=se ndp;
--swpstate1.sws;
++swpstate1 .lfs;
}
swpstate1.hdr.ack num=0; //ACK 清空
swpstate1.hdr.flags=0; // 存储缓冲池清空
printf("最近收到的ACK的帧序号:%ld\n",r);
//输出最近收到的ACK帧序号
printf(" 最近发送的帧序号(发送新帧后):%ld\n",swpstate1.lfs);
//输出最近发送帧序号
(2)接收方的接收原则从总体上看是先判断输入的数据帧是否在接收范围之内,若是,则继续判断是否符合其他接收条件;若不是,则马上丢弃该数据帧,不再进行其他条件的判断。
struct sen dq_slot *se ndq_rear,*se ndp,*p3,*p4; // 设定变量
struct recvq_slot *recvp,*recvq_rear,*p1,*p2;
if(swpstate1.hdr.flags==0)