滑动窗口实验报告

合集下载

滑动窗口算法基本原理与实践

滑动窗口算法基本原理与实践

滑动窗⼝算法基本原理与实践学过计算机⽹络的同学,都知道滑动窗⼝协议(Sliding Window Protocol),该协议是的⼀种应⽤,⽤于⽹络数据传输时的流量控制,以避免拥塞的发⽣。

该协议允许发送⽅在停⽌并等待确认前发送多个数据分组。

由于发送⽅不必每发⼀个分组就停下来等待确认。

因此该协议可以加速数据的传输,提⾼⽹络吞吐量。

滑动窗⼝算法其实和这个是⼀样的,只是⽤的地⽅场景不⼀样,可以根据需要调整窗⼝的⼤⼩,有时也可以是固定窗⼝⼤⼩。

滑动窗⼝算法(Sliding Window Algorithm)Sliding window algorithm is used to perform required operation on specific window size of given large buffer or array.滑动窗⼝算法是在给定特定窗⼝⼤⼩的数组或字符串上执⾏要求的操作。

This technique shows how a nested for loop in few problems can be converted to single for loop and hence reducing the timecomplexity.该技术可以将⼀部分问题中的嵌套循环转变为⼀个单循环,因此它可以减少时间复杂度。

简⽽⾔之,滑动窗⼝算法在⼀个特定⼤⼩的字符串或数组上进⾏操作,⽽不在整个字符串和数组上操作,这样就降低了问题的复杂度,从⽽也达到降低了循环的嵌套深度。

其实这⾥就可以看出来滑动窗⼝主要应⽤在数组和字符串上。

基本⽰例如下图所⽰,设定滑动窗⼝(window)⼤⼩为 3,当滑动窗⼝每次划过数组时,计算当前滑动窗⼝中元素的和,得到结果 res。

可以⽤来解决⼀些查找满⾜⼀定条件的连续区间的性质(长度等)的问题。

由于区间连续,因此当区间发⽣变化时,可以通过旧有的计算结果对搜索空间进⾏剪枝,这样便减少了重复计算,降低了时间复杂度。

课程设计报告滑动窗口协议仿真

课程设计报告滑动窗口协议仿真

滁州学院课程设计报告课程名称:计算机网络第五组起止日期:2011年n 月24 口~2011年12月7 n 指导教师:设计题目:滑动窗口协议仿贞 别: 计算机与信息工程学院业: 计算机科学与技术计算机与信息工程学院二O —一年制别:赵国柱课程设计任务书一.引言二-基本原理窗口机制Ibit滑动窗口协议后退N协议选择重传协议流量控制三.需求分析课程设计题目开发环境运行环境课程设计任务及要求界面要求网络接口要求0. 详细设计结构体的定义发送方的主要函数接受方的主要函数五. 源代码发送方的主要代码接收方的主要代码调试与操作说明致谢[参考文献]课程设计的主要内容L引言早期的网络通信中,通信双方不会考虑网络的拥挤情况直接发送数据。

由于大家不知道网络拥塞状况,一起发送数据,导致中间结点阻塞掉包,谁也发不了数据。

在数据传输过程中,我们总是希望数据传输的更快一些,但如果发送方把数据发送的过快,接收方就可能來不及接收,这就造成数据的丢失。

因此就有了滑动窗口机制来解决这些问题。

早期我们使用的是Ibit滑动窗口协议,一次只发送一个帧,等收到ack确认才发下一个帧,这样对信道的利用率太低了。

因此提出了一种采用累积确认的连续ARQ协议,接收方不必对收到的帧逐个发送 ack确认,而是收到儿个帧后,对按序到达的最后一个帧发送ack确认。

同Ibit滑动窗口协议相比,大大减少了 ack数量,并消除了延迟ack对传输效率的影响。

但是,这会产生一个新的问题,如果发送方发送了 5个帧,而中间的第3个帧丢失了。

这时接收方只能对前2个帧发出确认。

发送方无法知道后面三个帧的下落,只好把后面的3个帧再重传一次,这就是回退N协议。

为了解决这个问题,乂提出了选择重传协议。

当接收方发现某帧出错后,继续接受后面送来的正确的帧,只是不交付它们, 存放在自己的缓冲区中,并且要求发送方重传出错的那一帧。

一S收到重传來的帧后,就可以将存于缓冲区中的其余帧一并按正确的顺序递交给主机。

窗口技术实验报告(3篇)

窗口技术实验报告(3篇)

第1篇一、实验目的1. 理解窗口技术的概念和原理。

2. 掌握窗口的基本操作,如创建、显示、隐藏、移动和关闭。

3. 学习使用窗口技术实现简单的图形用户界面(GUI)。

二、实验环境1. 操作系统:Windows 102. 开发工具:Visual Studio 20193. 编程语言:C三、实验原理窗口技术是图形用户界面(GUI)设计的基础,它允许用户通过图形界面与计算机系统进行交互。

在C中,窗口通常是通过Windows窗体(Windows Forms)实现的。

每个窗体都是一个窗口,可以包含各种控件,如按钮、文本框、列表框等,以实现与用户的交互。

四、实验步骤1. 创建窗体打开Visual Studio 2019,创建一个新的Windows Forms App (.NET Framework) 项目。

在解决方案资源管理器中,双击Form1,打开窗体设计器。

2. 添加控件在工具箱中找到所需的控件,如按钮(Button)、标签(Label)、文本框(TextBox)等,并将它们拖放到窗体上。

3. 设置控件属性双击控件,在属性窗口中设置控件的属性,如名称、文本、位置、大小等。

4. 编写事件处理程序双击控件,在事件处理器中编写代码,以响应用户的操作,如按钮点击事件。

5. 测试窗体运行程序,测试窗体的功能,确保所有控件和功能按预期工作。

五、实验内容1. 创建一个简单的计算器创建一个包含数字按钮、运算符按钮和结果显示框的简单计算器。

用户可以通过点击按钮输入数字和运算符,然后点击等号按钮得到计算结果。

2. 实现一个简单的信息提示框创建一个窗体,包含一个按钮和一个标签。

点击按钮后,标签显示一条信息提示。

3. 实现窗口的基本操作编写代码实现窗口的创建、显示、隐藏、移动和关闭。

六、实验代码示例以下是一个简单的计算器窗体的代码示例:```csharpusing System;using System.Windows.Forms;namespace WindowsFormsApp{public partial class CalculatorForm : Form{public CalculatorForm(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){// 处理数字按钮点击事件}private void buttonAdd_Click(object sender, EventArgs e){// 处理加号按钮点击事件}private void buttonEqual_Click(object sender, EventArgs e){// 处理等号按钮点击事件}private void buttonClear_Click(object sender, EventArgs e){// 处理清除按钮点击事件}}}```七、实验结果与分析通过本次实验,我们成功创建了一个简单的计算器,实现了窗口的基本操作。

数据链路层滑动窗口协议的设计与实现

数据链路层滑动窗口协议的设计与实现

数据链路层滑动窗口协议的设计与实现实验报告一、实验任务及内容利用所学数据链路层原理,设计一个滑动窗口协议并在仿真环境下编程实现有噪音信道环境下的可靠的双工通信。

信道模型为8000bps 全双工卫星信道,信道传播时延270 毫秒,信道误码率为10-5,信道提供字节流传输服务,网络层分组长度在240~256字节范围。

(1)实现有噪音信道环境下的无差错传输。

(2)运行程序并检查在信道没有误码和存在误码两种情况下的信道利用率。

(3)提高滑动窗口协议信道利用率,根据信道实际情况合理地为协议配置工作参数,包括滑动窗口的大小和重传定时器时限以及ACK 搭载定时器的时限。

实验环境Windows 7环境PC机,Microsoft Visual C++ 6.0 集成化开发环境二、协议设计协议的分层结构及层服务:包括物理层,数据链路层和网络层三层。

该实验主要设计数据链路层协议,为实现有噪声环境下高信道利用率传输,我们采用回退n帧(go back n)技术的协议。

发送方窗口大小为31;通过捎带确认来完成可靠的数据通信;出现信道误码导致收帧出错时,接受方丢弃所有后续帧,待定时器超时后发送方重发。

该层提供服务:从网络层接受要发送的数据包,将之分拆成数据帧;按一定的成帧方案完成分帧,加校验码,加ack等操作;进行适当的流量判断和拥塞控制;启动定时器将之传递给物理层。

数据帧经信道传送给接受方,接受方数据链路层执行与成帧相逆的操作;处理ack信息,终止定时器(或启动ack定时器,ack成帧传送);判断是否为欲接受数据,数据是否出错,提交给网络层。

退回N步工作原理示意图:实验所形成帧(成帧方案):DATA Framen+=========+========+========+===============+========+| KIND(1) | ACK(1) | SEQ(1) | DATA(240~256) | CRC(4) |+=========+========+========+===============+========+ACK Frame+=========+========+========+| KIND(1) | ACK(1) | CRC(4) |+=========+========+========+NAK Frame+=========+========+========+| KIND(1) | ACK(1) | CRC(4) |+=========+========+========+CRC校验和的多项式定义:本次实验采用的CRC校验方案为CRC-32,与IEEE802.3 以太网校验和生成多项式相同。

计算机网络--滑动窗口实验报告

计算机网络--滑动窗口实验报告

计算机网络--滑动窗口实验报告计算机网络滑动窗口协议实验报告目录一、实验内容和实验环境描述(2)1.实验内容(2)2.实验目的(2)3.实验环境(2)二、协议设计(3)三、软件设计(4)Part A 选择重传协议1.数据结构(4)2.模块结构(6)3.算法流程(7)Part B gobackn协议 1.数据结构(8)2.模块结构(9)3.算法流程(10)四、实验结果分析(11)五、探究问题(13)六、实验总结与心得体会(14)一、实验内容和实验环境描述1.实验内容利用所学数据链路层原理,自己设计一个滑动窗口协议,在仿真环境下编程实现有噪音信道环境下两站点之间无差错双工通信。

信道模型为8000bps全双工卫星信道,信道传播时延270毫秒,信道误码率为10?5,信道提供字节流传输服务,网络层分组长度固定为 256 字节。

2.实验目的通过该实验,进一步巩固和深刻理解数据链路层误码检测的CRC校验技术,以及滑动窗口的工作机理。

滑动窗口机制的两个主要目的:(1)实现有噪音信道环境下的无差错传输;(2)充分利用传输信道的带宽。

在程序能够稳定运行并成功实现第一个目标之后,运行程序并检查在信道没有误码和存在误码两种情况下的信道利用率。

为实现第二个目标,提高滑动窗口协议信道利用率,需要根据信道实际情况合理地为协议配置工作参数,包括滑动窗口的大小和重传定时器时限以及 ACK 搭载定时器的时限。

3.实验环境Windows10环境PC机Microsoft Visual Studio 2017集成开发环境二、协议设计本次试验主要设计数据链路层,实验中分别设计了gobackn协议与选择重传协议。

主要涉及到的层次结构是物理层、数据链路层、网络层。

物理层:为数据链路层提供的服务为8000bps,270ms传播延时,10?5误码率的字节流传输通道。

数据链路层利用接口函数send_frame()和 recv_frame()从物理层发送和接收一帧。

滑动窗口协议实验报告

滑动窗口协议实验报告

滑动窗口协议实验报告1. 引言滑动窗口协议是计算机网络中用于实现可靠数据传输的一种协议。

其核心思想是使用一个窗口来管理发送方和接收方之间的数据传输进程,通过滑动窗口的机制来实现流量控制和错误恢复。

本实验旨在通过编写滑动窗口协议的模拟程序,深入理解该协议的工作原理及其在数据传输中的应用。

2. 实验环境本次实验采用C++语言进行编程,并在Windows操作系统下进行测试。

3. 实验过程3.1 窗口大小的确定首先,我们需要确定滑动窗口的大小。

在实际应用中,窗口大小需要根据网络状况来调整,以保证传输效率。

本次实验中,我们设置窗口大小为5。

3.2 发送方逻辑实现发送方负责将数据分割为若干个数据包,并发送给接收方。

发送方需要维护发送窗口的起始位置和结束位置,在每次发送数据包后,将发送窗口向前滑动一格。

如果接收窗口收到接收方的确认信息,发送方将收到确认的数据包从发送窗口中移除,并将窗口向前滑动一格。

3.3 接收方逻辑实现接收方需要维护接收窗口的起始位置和结束位置。

当接收窗口收到数据包时,接收方首先检查数据包的顺序是否正确,如果顺序正确,则将数据包保存并发送确认信息给发送方。

接收方随后将接收窗口向前滑动一格,等待下一个数据包的到来。

3.4 测试与验证在实验过程中,我们通过模拟网络传输的延迟、丢包等情况来验证滑动窗口协议的可靠性。

通过调整滑动窗口的大小以及模拟网络传输的不同情况,我们可以观察到滑动窗口协议在不同场景下的性能表现。

4. 实验结果分析通过实验,我们观察到滑动窗口协议在正常网络传输情况下,能够实现高效的数据传输。

当网络传输出现延迟或丢包时,滑动窗口协议能够通过重传机制和流量控制策略,确保数据的可靠传输。

在窗口大小适当的情况下,滑动窗口协议能够最大化利用网络带宽,提高数据传输的效率。

5. 实验总结本次实验通过编写模拟程序,深入理解了滑动窗口协议的工作原理及其在数据传输中的应用。

滑动窗口协议通过窗口的滑动机制,实现了对数据传输过程的控制和管理,从而保证了数据的可靠性和传输效率。

滑动窗口协议

滑动窗口协议

实验四滑动窗口协议1、实验目的(1)掌握滑动窗口协议的概念、原理与基本算法。

(2)理解3种典型的数据链路层滑动窗口协议:l位滑动窗口协议、使用退后n帧的滑动窗口协议与使用选择性重传的滑动窗口协议。

(3)了解传输层与数据链路层滑动窗口协议的区别与联系,了解TCP滑动窗口协议的实现原理。

2、实验要求编程实现使用选择性重传策略的滑动窗口协议模拟程序:(1)所有功能应可视,具有简单的界面。

(2)由一台PC向另一台PC发送数据包,界面中应动态显示数据帧的发送和接收情况,以表明协议模拟程序的正确运作过程。

(3)当发送方速度过快或帧丢失时,接收方应发送消息,要求暂停或者重传。

接收方应按序向网络层提交接收到的帧。

(4)发送方应可设置发送速度、滑动窗口数目、停止等待等的超时时间间隔以及发送类型(用于模拟信道错误如正常发送,帧校验错,帧丢失)等参数。

3、实验环境微机一台、Visual Studio 6.0集成开发环境。

4、实验相关知识滑动窗口协议的流量控制:发送方窗口内的序列号代表已经发送但尚未确认的帧,一旦窗口达到最大值,发送方的数据链路层必须强行关闭网络层直到有一帧缓冲区可用为止。

接收方数据链路层的窗口对应于允许接收的帧。

任何落在接收窗口之外的帧都不加说明地丢弃。

滑动窗口协议的差错控制:使用后退n帧技术:接收端丢弃出错帧后所有的帧,而不管这些帧是正确的还是出错的;对应于接收窗口的尺寸为1的情况;如果信道错误率高,将会浪费大量的带宽。

选择性重传策略:信道出错时,接收方将存储所有跟在坏帧之后的正确帧,并只要求发送方重传出错的帧;对应于接收窗口大于1的情况。

两种差错控制策略的收发过程比较:5 系统实施5.1程序的主要流程图5.2主要过程关于发送端网络层数据流量的模拟:为了使协议模拟尽量简化,事先做两个假设:假设1:发送方的网络层总有数据需要发送;假设2:接收方没有反向流量,因此不能捎带确认,每次等待辅助定时器超时之后发送一个单独的确认帧(ACK或NAK)。

计算机网络实验 (5)精选全文完整版

计算机网络实验 (5)精选全文完整版

可编辑修改精选全文完整版计算机网络实验1. 编程实验(使用NetRiver实验系统)(1)滑动窗口协议实验(见实验指导书的实验1,只做回退N帧实验)(2)IPv4协议收发实验(见实验指导书的实验2)(3)IPv4协议转发实验(见实验指导书的实验3)每位同学只做其中的一个实验,学号mod 3 = 0、1、2的同学分别做实验1、2、3。

程序应通过测试服务器的测试;程序及实验报告应提交到管理服务器供检查。

实验报告包括以下几部分内容:实验目的,协议的工作原理或处理要求,程序流程图。

提交的代码应有必要的注释。

2. 交互式实验(使用NetRiver实验系统)(1)IPv4协议交互实验(见实验指导书的实验11)(2)TCP协议交互实验(见实验指导书的实验14)该实验所有同学都要做。

服务器会自动记录实验结果,不需提交实验报告。

3. 观察实验(使用协议分析工具Wireshark)该实验所有同学都要做。

3.1观察IEEE 802.3帧结构进行实验的主机运行Windows XP操作系统。

通过Wireshark将实验主机的网卡设置为通常模式(非混杂模式),捕捉以下场景中的数据帧:先在命令行下用arp –d命令删除实验主机上的所有ARP表项,接着立即用web浏览器访问Internet上的站点。

1)依次查看捕获的各数据帧,看看目的地为实验主机的数据帧中长度最小的是多大;查看这种帧的各个域,看看前导码是否包含在记录的数据中;记录的数据是从哪个字段开始,至哪个字段结束;这是否验证了IEEE 802.3标准中规定的最小帧长为64字节?2)查看捕获的帧中长度最长的帧。

可以多访问一些网页以捕获更多的帧,看看这些帧的长度最大是多少?为什么?3)查看捕获的数据帧中由实验主机发出的ARP请求帧,查看封装该ARP 请求帧的以太帧的目的地址是多少,源地址是多少;再用ipconfig –all命令查看实验主机的MAC地址,看看是否和源地址一致。

滑动窗口实验报告

滑动窗口实验报告

实验目的:了解滑动窗口技术的原理和应用,通过实验验证滑动窗口在信号处理、图像处理和文本分析等领域的有效性。

实验环境:操作系统:Windows 10编程语言:Python 3.8库:NumPy、Matplotlib、Pandas实验内容:1. 滑动窗口在信号处理中的应用2. 滑动窗口在图像处理中的应用3. 滑动窗口在文本分析中的应用实验一:滑动窗口在信号处理中的应用1. 实验目的通过实验验证滑动窗口在信号处理中的有效性,对信号进行平滑处理,减少噪声干扰。

2. 实验步骤(1)导入NumPy库,生成一个包含噪声的信号;(2)定义滑动窗口函数,实现信号的平滑处理;(3)绘制原始信号和经过滑动窗口处理后的信号;(4)分析实验结果。

3. 实验代码```pythonimport numpy as npimport matplotlib.pyplot as plt# 生成信号signal = np.sin(np.linspace(0, 10, 100)) + np.random.normal(0, 0.5, 100)# 定义滑动窗口函数def moving_average(data, window_size):weights = np.ones(window_size) / window_sizereturn np.convolve(data, weights, mode='valid')# 处理信号window_size = 5smoothed_signal = moving_average(signal, window_size)# 绘制信号plt.figure(figsize=(10, 5))plt.plot(signal, label='Original Signal')plt.plot(np.arange(window_size // 2, len(signal) - window_size // 2), smoothed_signal, label='Smoothed Signal')plt.legend()plt.show()```4. 实验结果实验结果表明,经过滑动窗口处理后的信号相对于原始信号更加平滑,噪声干扰得到了有效抑制。

实验一 滑动窗口协议实验

实验一  滑动窗口协议实验

实验一滑动窗口协议实验◆实验目的:在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及选择重传三种协议,它们的差别仅在于各自窗口尺寸的大小不同而已。

网络实验091220033_lab01

网络实验091220033_lab01

《计算机网络协议开发》实验报告第一次实验:滑动窗口协议实验姓名:葛鑫学号:0912200332009 级计算机系一班邮箱:xingenju@时间:2012/2/26一、实验目的在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实验任务对实际系统中的协议分层和协议软件的设计与实现有基本的认识。

2实验内容利用所学数据链路层原理,自己设计一个滑动窗口协议并在仿真环境下编程实现有噪音信道环境下的可靠的双工通信。

信道模型为8000bps 全双工卫星信道,信道传播时延270 毫秒,信道误码率为10-5,信道提供字节流传输服务,网络层分组长度在240~256字节范围。

通过该实验,进一步巩固和深刻理解数据链路层的字节填充方式的成帧技术,误码检测的CRC 校验技术,以及滑动窗口的工作机理。

滑动窗口机制的两个主要目标:(1) 实现有噪音信道环境下的无差错传输; (2)充分利用传输信道的带宽。

在程序能够稳定运行并成功实现第一个目标之后,运行程序并检查在信道没有误码和存在误码两种情况下的信道利用率。

为实现第二个目标,提高滑动窗口协议信道利用率,需要根据信道实际情况合理地为协议配置工作参数,包括滑动窗口的大小和重传定时器时限以及ACK 搭载定时器的时限。

这些参数的设计,需要充分理解滑动窗口协议的工作原理并利用所学的理论知识,经过认真的推算,计算出最优取值,并通过程序的运行进行验证。

对实际系统中的协议分层和协议软件的设计与实现有基本的认识。

3编程环境利用仿真环境下所提供的物理层服务和定时器机制为网络层提供服务。

8.1程序的总体结构设数据链路层通信的两个站点分别为站点A和站点B,仿真环境利用WindowsXP环境下的TCP协议和Socket客户端/服务器机制构建两个站点之间的通信,其中,站点A为服务器端,站点B为客户端。

编译、链接之后最终生成的可执行程序(.exe文件)为字符界面命令行程序(不是图形界面程序)。

可执行程序文件仅有一份,设为datalink.exe,在WindowsXP 的两个DOS 窗口中使用不同的命令行参数启动两个进程,分别仿真站点A和站点B。

8.2实验环境所提供的文件和编译运行方法实验环境使用Visual C++ 6.0系统datalink.dsw,datalink.dsp:Microsoft VC6.0的工程文件,包括Win32 Debug和Win32 Release两种配置。

实验三:滑动窗口协议的实现

实验三:滑动窗口协议的实现

实验三滑动窗口协议的实现实验目的理解滑动窗口协议对连续ARQ协议的改进,及其在流量控制中的意义实验内容在Visual C++环境中,通信的双方在应用中根据滑动窗口协议的思想进行流量控制。

需要处理正常数据与应答、出错数据、丢失数据、丢失应答等各种情况,并进行统计。

要求提供图形化输出,具体可参考实验要求中的详细说明。

实验要求1.任何一个节点都具备发送和接收的功能,主操作界面如图1。

图1 主界面发送窗口的大小在发送参数中设置,发送时,界面上的发送窗口动态变化,对应当前已发送的数据,图中,黄色表示不在当前发送窗口中的序号;绿色表示在发送窗口中已经发送了的数据序号;蓝色表示在发送窗口中,还没有发送的数据序号。

接收窗口也需要动态表示当前的可接收序号(蓝色表示)。

2.发送文件1)设置发送参数在中输入文件的接收方IP地址,点击图1的“发送参数设置”按钮,出现图2的界面,对停等协议的发送方参数进行设定。

图2 设置发送参数2)选择发送文件从图1的点击“浏览”,出现图3的弹出窗口,可从本机选择需要发送的文件,要求文件大于1M字节。

图3 选择发送的文件3)发送文件选定文件后点击“发送”按钮,发送数据的信息在图1 显示,包括所有分组的传输信息。

4)根据确认状态,完成下一步操作ACK:正确接收,已收到确认-------发送下一个数据分组未ACK:未收到确认信息------在到达设置的超时时间后仍未收到确认,则重新发送原分组NAK:收到否定确认-----直接重传原来的分组5)发送完成,显示统计信息统计信息可包括:文件总长度,发送的分组数目,收到ACK、NAK等的次数,超时重发次数、错误重发次数等相关信息。

6)保存发送过程明细记录点击图1左下方的按钮,调用类似图3的界面,将发送的明细信息保存到文件中,以便查看。

3.接收文件当节点作为信息的接收方,首先可以选择两种应答方式:自动应答和手动应答。

1)在收到某个用户的第一个分组时,给出如图4的接收提示。

滑动窗口协议实验报告

滑动窗口协议实验报告

滑动窗口协议实验报告篇一:实验二滑动窗口协议实验报告2<滑动窗口协议的模拟>项目设计报告作者:完成日期:签收人:签收日期:1 需求分析实验目的:加深对滑动窗口协议的理解实验任务:实现对于滑动窗口协议的模拟实验环境:PC机操作系统:Windows XP开发环境:Microsoft Visual C++ ,可以使用MFC类库问题重述界面要求:项目要求的所有功能应可视,要有简单的界面。

由一台PC(或线程)向另一台PC (或线程)发送数据包时,界面应显示出双方帧个数的变化,帧序号,发送和接受速度,暂停或重传提示等,界面中必须动态显示数据帧的发送和接受情况,包括在相应的窗口详细显示相应的ACK和其他收发数据帧后发出的消息,以表明模拟协议的正确运作过程。

在各种情况下,接受方和发送方窗口应实时显示帧的发送和接受情况,包括序号,时间戳,内容等。

以及窗口的填充和清空情况。

网络接口要求:两台机器或是一台机器中两个独立的线程模拟发送方与接受方,接收数据的端口初始应为监听状态。

发送方向接受方发起连接,成功后开始发送数据。

接受方要求:接受方应由固定大小的滑动窗口,并对收到信息缓存。

当发送方速度过快或帧丢失(超时),接受方应发送消息,要求暂停或是重传(停---等协议)。

接受方要求按序向网络层提交收到的帧。

发送方要求:发送方发送速度可以调节,并可以暂停或是重发。

发送方重传时可仅重传需要的帧。

可指定滑动窗口数目和要发送的帧的总数,停等的超时时间间隔以及发送类型(正常发送,错序发送,以及缺帧,丢帧的现象),发送速率等参数。

2 概要设计原理概述发送方和接受方都维持了一个窗口,窗口内部包含了那些可以接受的序列号。

发送方的窗口大小从0开始,以后可以增大到某一个预设的最大值。

由于发送方可能在将来的某个时刻重传未被确认的帧,所以它必须把已经送出去的帧保留一段时间,直到他知道接受方已经接受了这些帧。

当第n帧的确认到来时,第n-1,第n-2等也都被自动地确认了。

滑动窗口算法在时序数据处理中的应用研究

滑动窗口算法在时序数据处理中的应用研究

滑动窗口算法在时序数据处理中的应用研究随着数据采集和存储技术的不断提升,时序数据在各个领域中得到了广泛的应用,如物联网、金融、医疗等领域。

而时序数据的处理和分析,对于业务的决策和应用具有至关重要的作用。

滑动窗口算法作为一种重要的时序数据处理方法,已经在实际应用中得到了充分的验证和应用。

一、滑动窗口算法概述滑动窗口算法(Sliding Window)是一种经典的算法,主要用于处理一些固定大小的连续区间问题。

例如,维护某个时间窗口内的数据,求解某个序列中最小值的位置等等。

其基本思想是:维护一个大小为k的窗口,从前往后遍历序列,每遍历一个新的元素,就将窗口向右移动一个单位,舍弃一个旧元素,加入一个新元素。

在滑动窗口算法中,窗口相当于一个缓存区,可以根据业务需求选择窗口大小。

每当窗口移动一个单位时,都会有一个新的数据进入窗口,这个数据会被加入到窗口的尾部,同时,窗口的头部的数据会被舍弃掉。

这样,每次只需要对新添加的数据进行处理,而不需要重新处理整个序列数据。

二、滑动窗口算法在时序数据处理中的应用1. 数据采样在很多实时应用中,需要对数据进行采样,以抽取足够多的数据以进行分析。

滑动窗口算法可以很好地支持数据采样工作。

具体实现时,可以通过设置窗口大小和窗口移动步长来进行采样,保证采样数据量的合理性,并且减少数据处理时间,提高处理效率。

2. 数据分析滑动窗口算法可以帮助我们快速分析时序数据,在业务需求中很常见。

例如,在网站流量分析中,需要实时计算某个时间段内的PV、UV变化趋势。

此时,可以采取滑动窗口算法,维护一个时间窗口,使得窗口内的数据时刻更新,以便对最新的数据进行分析,从而得到每个时间点的PV和UV结果。

3. 数据预测时序数据预测是一项重要的任务,为许多领域提供了决策基础。

滑动窗口算法可以帮助我们快速进行时序数据预测。

具体实现时,选取一个固定窗口大小,根据历史数据进行预测;每次窗口移动时,对预测结果进行重新计算。

资料:计算机网络_回退N帧_PB10011052_张剑格

资料:计算机网络_回退N帧_PB10011052_张剑格

计算机网络实验报告姓名:张剑格学号:PB10011052滑动窗口协议回退N帧实验实验报告❖实验目的计算机网络的数据链路层协议保证通信双方在有差错的通信线路上进行无差错的数据传输,是计算机网络各层协议中通信控制功能最典型的一种协议。

本实验实现一个数据链路层协议的数据传送部分,目的在于帮助更好地理解数据链路层协议中的“滑动窗口”技术的基本工作原理,掌握计算机网络协议的基本实现技术。

❖实验要求在一个数据链路层的模拟实现环境中,用C语言实现停等及退回N帧滑动窗口协议,响应系统的发送请求、接收帧消息以及超时消息,并根据滑动窗口协议进行相应处理。

❖协议工作原理➢滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。

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

➢回退N帧协议从滑动窗口的观点来来看,属于发窗口>1,接收窗口>1的情况。

❖协议处理要求测试函数包括停等协议测试函数stud_slide_window_stop_and_wait和回退N帧协议测试函数stud_slide_window_back_n_frame,在下列情况系统会调用测试函数:➢当发送端需要发送帧时,会调用测试函数,并置参数messageType为MSG_TYPE_SEND,测试函数应该将该帧缓存,存入发送队列中。

若发送窗口还未打开到规定限度,则打开一个窗口,并将调用SendFRAMEPacket函数将该帧发送。

若发送窗口已开到限度,则直接返回,相当于直接进入等待状态。

➢当发送端收到接收端的ACK后,会调用测试函数,并置参数messageType为MSG_TYPE_RECEIVE,测试函数应该检查ACK值后,将该ACK对应的窗口关闭。

由于关闭了窗口,等待发送的帧可以进入窗口并发送,因此,此时若发送队列中存在等待发送的帧应该将一个等待发送的帧发送并打开一个新的窗口。

(完整word版)滑动窗口协议报告 (2)

(完整word版)滑动窗口协议报告 (2)

滑动窗口协议设计报告滑动窗口协议设计1、引言随着网络的不断壮大,用户数量、信息量的需求不断增加,网络负荷越来越重。

此时,我们迫切需要一种机制来控制网络的流量,减少网络拥堵的几率,提高传输的效率。

因此,一种名为滑动窗口的协议应运而生。

滑动窗口协议,是TCP使用的一种流量控制方法。

该协议允许发送方在停止并等待确认前可以连续发送多个分组。

由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。

经测试证明,该协议还能有效地解决TCP的高协议处理开销和UDP的低可靠性之间的矛盾。

2、实验目的基本原理2.1 窗口机制滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。

发送窗口和接收窗口的序号的上下界不一定要一样,甚至大小也可以不同。

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

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

接受方为其窗口内的每一个序号保留了一个缓冲区。

与每个缓冲区相关联的还有一位,用来指明该缓冲区是满的还是空的。

3、实验原理TCP滑动窗口用来暂存两台计算机问要传送的数据分组。

每台运行TCP协议的计算机有两个滑动窗口:一个用于数据发送,另一个用于数据接收。

发送端待发数据分组在缓冲区排队等待送出。

被滑动窗口框入的分组,是可以在未收到接收确认的情况下最多送出的部分。

滑动窗口左端标志X的分组,是已经被接收端确认收到的分组。

随着新的确认到来,窗口不断向右滑动4、实验代码#include<stdio.h>#include <stdlib.h>#include <windows.h>//加这个头文件#include <windowsx.h>#include <iostream>#include <winsock.h>#include<conio.h>#include<time.h>#include <math.h>#define NULL 0#define MAX_LENGTH 2000#define RECEIVE_MAX_LENGTH 1500#define SEND_MAX_LENGTH 1500#define TIMEOUT 1#define WSA_WAIT_TIMEOUT -1#define MAXPOOL 100#define SLEEPMS 1000#define SOCKET_DISCONN 0#pragma comment(lib,"ws2_32.lib")#pragma warning(disable:4996)typedef enum { data = 1, ack, nak, tout } frame_kind; //帧类型CRITICAL_SECTION gCS;int socketClient;int ret;typedef struct frame_head{frame_kind kind; //帧类型unsigned int seq; //序列号unsigned int ack; //确认号unsigned char data[MAX_LENGTH]; //数据}Head;typedef struct frame{frame_head head; //帧头unsigned int size; //数据的大小} Frame;typedef struct framenode //队列节点类型{frame head_data;struct framenode *next;} Framenode;typedef struct{Framenode *front; //队头指针Framenode *rear; //队尾指针} LinkQueue;void InitLine(LinkQueue *q){q->front = q->rear =NULL;}int QueueEmpty(LinkQueue *q){return q->front == NULL && q->rear == NULL; }frame QueueFront(LinkQueue *q){if (QueueEmpty(q)){printf("队列为空!\n");Sleep(SLEEPMS);exit(0);}return q->front->head_data;}int QueueLen(LinkQueue *q){if (QueueEmpty(q)){return 0;}int num = 0;Framenode *p = q->front;while (p != NULL){num++;p = p->next;}return num;}void GetFrameFromHost(LinkQueue *q){if (QueueLen(q) >= MAXPOOL){printf("data %d 已准备好\n", q->front->head_data.head.seq);return;}Framenode *p = (Framenode *)malloc(sizeof(Framenode));memset(p->head_data.head.data, 0, MAX_LENGTH);srand((unsigned)time(NULL));p->head_data.size = rand() % MAX_LENGTH; // 帧大小随机生成memset(p->head_data.head.data, '1', p->head_data.size);p->head_data.head.ack = -1;p->head_data.head.kind = data;p->head_data.head.seq = 0;p->next = NULL;if (QueueEmpty(q))q->front = q->rear = p; // 首帧是待发送的帧else{p->head_data.head.seq = (q->rear->head_data.head.seq + 1) % MAXPOOL;q->rear->next = p;q->rear = p;}printf("从主机得到:data %d,放入缓存\n", p->head_data.head.seq);GetFrameFromHost(q); // 由于实验需要,假设主机有足够多的数据帧要发送}void DeLine(LinkQueue *q){Framenode *p = NULL;if (QueueEmpty(q)){printf("队列为空!\n");}else{p = q->front;q->front = p->next;if (q->rear == p) q->rear = NULL;printf("发送data %d, %d 成功!从缓存中删除\n", p->head_data.head.seq, p->head_data.size);free(p);p = NULL;}}void main(){printf("建立连接 ... \n");Begin:WORD wVersionRequested;DWORD WINAPI ReceiveFun(LPVOID pParam);WSADATA wsaData; //初始化socket库wVersionRequested = MAKEWORD(1, 1); //两个byte型合并成一个WORD型int err = WSAStartup(wVersionRequested, &wsaData);if (err != 0){Sleep(SLEEPMS);return;}if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1){WSACleanup(); //中止Windows Sockets服务 WSAStartup()成对使用Sleep(SLEEPMS);return;}socketClient = socket(AF_INET, SOCK_STREAM, 0);//监听的套接字SOCKADDR_IN clientadd;clientadd.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");clientadd.sin_family = AF_INET;clientadd.sin_port = htons(7001);//设置连接端的IP、端口if (SOCKET_ERROR ==connect(socketClient, (SOCKADDR*)&clientadd, sizeof(SOCKADDR))) //连接{WSACleanup();Sleep(SLEEPMS);goto Begin;}char getData[RECEIVE_MAX_LENGTH];memset(getData, 0, RECEIVE_MAX_LENGTH); //清零if (recv(socketClient, getData, RECEIVE_MAX_LENGTH, 0) == SOCKET_ERROR) //接受printf("接受连接提示信息出错!\n");}else{printf("%s\n", getData);}char sendData[SEND_MAX_LENGTH];memset(sendData, 0, SEND_MAX_LENGTH);strcpy(sendData, "你好接收方,我是发送方!");if (SOCKET_ERROR == send(socketClient, sendData, strlen(sendData) + 1, 0)) //发送{printf("发送连接提示信息出错!\n");WSACleanup();closesocket(socketClient);Sleep(SLEEPMS);return;}printf("按任意键继续!\n");while (!kbhit()) {}; //等待开始Sleep(SLEEPMS);printf("1bit滑动窗口协议:发送方,发送窗口=1\n");LinkQueue QueueQ;InitLine(&QueueQ);frame packetsend; //dataframe packetreceive; // ack,nakunsigned long tick = GetTickCount();int ret = 0;HANDLE hThread;while (1){GetFrameFromHost(&QueueQ); //从主机取数据帧memset(&packetsend, 0, sizeof(packetsend));Sleep(SLEEPMS);printf("\n");packetsend = QueueFront(&QueueQ); //取数据帧ret = send(socketClient, (char *)&packetsend, sizeof(packetsend), 0);//发送dataif (ret == SOCKET_ERROR){printf("发送数据出错!\n");continue;}printf("发送数据帧:data %d, %d\n", packetsend.head.seq, packetsend.size);const unsigned long timeOut = 5 * 1000; //设置超时计时器 5秒超时memset(&packetreceive, 0, sizeof(packetreceive));Sleep(SLEEPMS);printf("\n");InitializeCriticalSection(&gCS); // 初始化临界区hThread = CreateThread(NULL, 0, ReceiveFun, (LPVOID)&packetreceive, 0, NULL);int r = WaitForMultipleObjects(1, &hThread, TRUE, timeOut);DeleteCriticalSection(&gCS); //与InitializeCriticalSection(&gCS);成对使用if (ret == SOCKET_ERROR || ret == SOCKET_DISCONN){printf("接受出错!Press any key to continue\n");while (!kbhit()) {};continue;}if (r == WSA_WAIT_TIMEOUT) //判断超时{TerminateThread(hThread, 0); //终止线程printf("超时重传:data %d, %d\n", packetsend.head.seq, packetsend.size);}else if (packetsend.head.seq == packetreceive.head.ack){srand((unsigned)time(NULL));switch (rand() % 5) //假定产生随机结果,20%的概率超时{case 0:printf("接收方发送回复超时(ack丢失模拟):%d\n", packetsend.head.seq);printf("超时重传:data %d, %d\n", packetsend.head.seq, packetsend.size);break;default:if (packetreceive.head.kind == ack){printf("接受ack帧:ack %d\n", packetreceive.head.ack);DeLine(&QueueQ);}else if (packetreceive.head.kind == nak){printf("接受nak帧:nak %d\n", packetsend.head.seq);}break;}}else printf("帧序号出错: %d\n", packetreceive.head.ack);if (GetTickCount() - tick > 20 * TIMEOUT) //设置时间20秒{printf("持续时间20s. 按q退出,其他键继续\n");int kbc = getch();if (kbc == 'q' || kbc == 'Q')break;}}printf("按任意键退出!\n");while (!kbhit()) {};Sleep(SLEEPMS);printf("谢谢使用!\n");WSACleanup();closesocket(socketClient);Sleep(SLEEPMS);}DWORD WINAPI ReceiveFun(LPVOID pArg){EnterCriticalSection(&gCS);//进入critical sectionframe *packetreceive = (frame *)pArg;ret = recv(socketClient, (char *)packetreceive, sizeof(*packetreceive), 0);LeaveCriticalSection(&gCS); //线程用毕,离开critical sectionreturn ret;}#include<stdio.h>#include <stdlib.h>#include <windows.h>//加这个头文件#include <windowsx.h>#include <iostream>#include <winsock.h>#include<conio.h>#include<time.h>#include <math.h>#define NULL 0#define MAX_LENGTH 2000#define RECEIVE_MAX_LENGTH 1500#define SEND_MAX_LENGTH 1500#define TIMEOUT 1#define WSA_WAIT_TIMEOUT -1#define MAXPOOL 100#define SLEEPMS 1000#define SOCKET_DISCONN 0#pragma comment(lib,"ws2_32.lib")#pragma warning(disable:4996)typedef enum { data = 1, ack, nak, tout } frame_kind; //帧类型CRITICAL_SECTION gCS;int socketClient;int ret;typedef struct frame_head{frame_kind kind; //帧类型unsigned int seq; //序列号unsigned int ack; //确认号unsigned char data[MAX_LENGTH]; //数据}Head;typedef struct frame{frame_head head; //帧头unsigned int size; //数据的大小} Frame;typedef struct framenode //队列节点类型{frame head_data;struct framenode *next;} Framenode;typedef struct{Framenode *front; //队头指针Framenode *rear; //队尾指针} LinkQueue;void InitLine(LinkQueue *q){q->front = q->rear = NULL;}int QueueEmpty(LinkQueue *q){return q->front == NULL && q->rear == NULL; }frame QueueFront(LinkQueue *q){if (QueueEmpty(q)){printf("队列为空!\n");Sleep(SLEEPMS);exit(0);}return q->front->head_data;}int QueueLen(LinkQueue *q){if (QueueEmpty(q)){return 0;}int num = 0;Framenode *p = q->front;while (p != NULL){num++;p = p->next;}return num;}int GetFrameFromHost(LinkQueue *q){if (QueueLen(q) >= MAXPOOL){printf("准备接受:data %d \n", q->front->head_data.head.seq);return q->front->head_data.head.seq;}Framenode *p = (Framenode *)malloc(sizeof(Framenode));memset(p->head_data.head.data, 0, MAX_LENGTH);p->head_data.head.ack = -1;p->head_data.head.seq = 0;p->next = NULL;if (QueueEmpty(q))q->front = q->rear = p;else{p->head_data.head.seq = (q->rear->head_data.head.seq + 1) % MAXPOOL;q->rear->next = p;q->rear = p;}return GetFrameFromHost(q);}int DeLine(LinkQueue *q, frame *pf, unsigned int curw) //假设数据帧送往主机是足够快的{Framenode *p = NULL;if (curw == q->front->head_data.head.seq)p = q->front;elsep = q->rear;if (p->head_data.head.ack != -1) //假定数据已经提交主机{printf("向主机交付data %d, %d 成功!\n", p->head_data.head.ack, p->head_data.size);}memset(p->head_data.head.data, 0, MAX_LENGTH);memcpy(p->head_data.head.data, pf->head.data, pf->size);p->head_data.size = pf->size;p->head_data.head.ack = pf->head.seq; //保存发送帧序号}frame QueueAnswer(LinkQueue *q, unsigned int curw){if (curw == q->front->head_data.head.seq){return q->front->head_data;}else{return q->rear->head_data;}}void main(){Begin:WORD wVersionRequested;WSADATA wsaData; //初始化socket库wVersionRequested = MAKEWORD(1, 1); //两个byte型合并成一个WORD型int err = WSAStartup(wVersionRequested, &wsaData);//使用sockets之前要调用一次if (err != 0){Sleep(SLEEPMS);return;}if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1){WSACleanup();//中止Windows Sockets服务 WSAStartup()成对使用Sleep(SLEEPMS);}SOCKET socksrv = socket(AF_INET, SOCK_STREAM, 0);//监听的套接字SOCKADDR_IN socketadd;socketadd.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //监听连接socketadd.sin_family = AF_INET;socketadd.sin_port = htons(7001); //设置端口if (SOCKET_ERROR == bind(socksrv, (SOCKADDR*)&socketadd, sizeof(SOCKADDR))) {printf("绑定出错!\n");WSACleanup();Sleep(SLEEPMS);return;}if (SOCKET_ERROR == listen(socksrv, 5)){printf("监听出错!");WSACleanup();Sleep(SLEEPMS);return;}SOCKADDR_IN sockclient;int len = sizeof(SOCKADDR);SOCKET sockconn = accept(socksrv, (SOCKADDR*)&sockclient, &len);//建立连接的套节字if (INVALID_SOCKET == sockconn){printf("建立连接出错!\n");WSACleanup();Sleep(SLEEPMS);}char sendData[SEND_MAX_LENGTH];memset(sendData, 0, SEND_MAX_LENGTH);sprintf(sendData, "%s", "你好发送方,我是接受方!");if (SOCKET_ERROR == send(sockconn, sendData, strlen(sendData) + 1, 0)){printf("发送连接提示信息出错!\n");WSACleanup();closesocket(sockconn);Sleep(SLEEPMS);return;}char getData[RECEIVE_MAX_LENGTH];memset(getData, 0, RECEIVE_MAX_LENGTH);recv(sockconn, getData, RECEIVE_MAX_LENGTH, 0);printf("%s\n", getData);printf("1bit滑动窗口协议:接收方,接收窗口=1\n");LinkQueue QueueQ;InitLine(&QueueQ);frame packetreceive; //dataframe packetsend; // ack,nakint curw = GetFrameFromHost(&QueueQ);//初始化接收窗口int ret = 0;while (1){memset(&packetreceive, 0, sizeof(packetreceive));Sleep(SLEEPMS);printf("\n");ret = recv(sockconn, (char *)&packetreceive, sizeof(packetreceive), 0);if (ret == SOCKET_ERROR || ret == SOCKET_DISCONN){if (ret == SOCKET_ERROR){printf("连接出错!自动连接!\n");continue;}else{printf("连接已断开,按q退出,其他键等待新的连接\n");int kbc = getch();if (kbc == 'q' || kbc == 'Q')break;else{WSACleanup();closesocket(sockconn);Sleep(SLEEPMS);goto Begin;}}}srand((unsigned)time(NULL));switch (rand() % 5) //假定产生随机结果,20%的概率校验错误或接收发送方超时{case 0:printf("接受数据帧:data %d, %d,校验错误,丢弃(数据帧出错模拟)\n", packetreceive.head.seq, packetreceive.size);memset(&packetsend, 0, sizeof(packetsend));memcpy(&packetsend, &packetreceive, sizeof(packetreceive));packetsend.head.ack = packetreceive.head.seq;packetsend.head.seq = curw;packetsend.head.kind = nak;printf("发送否认帧:nak %d\n", packetreceive.head.seq);break;case 1:packetsend.head.kind = tout;printf("发送方发送数据超时(数据帧丢失模拟):%d\n", packetreceive.head.seq);break;default:printf("接受数据帧:data %d, %d,校验正确\n", packetreceive.head.seq, packetreceive.size);if (packetreceive.head.seq == (QueueAnswer(&QueueQ, curw)).head.ack){printf("上一帧的重发,丢弃,直接发送确认帧:ack %d\n", packetreceive.head.seq);}else{printf("新的数据帧:data %d, %d,放入缓存\n", packetreceive.head.seq, packetreceive.size);curw = DeLine(&QueueQ, &packetreceive, curw); //将新帧保存待送往主机memset(&packetsend, 0, sizeof(packetsend));packetsend = QueueAnswer(&QueueQ, curw); //待发送的确认帧printf("发送确认帧:ack %d\n", packetreceive.head.seq);}packetsend.head.kind = ack;break;}if (packetsend.head.kind == tout) continue; //发送方使用多线程判断超时ret = send(sockconn, (char *)&packetsend, sizeof(packetsend), 0);if (ret == SOCKET_ERROR){printf("发送ack或nak出错!自动连接!\n");continue;}}printf("按任意键退出!\n");while (!kbhit()) {};Sleep(SLEEPMS);cprintf("谢谢使用!\n");WSACleanup();closesocket(sockconn);Sleep(SLEEPMS);}5、实验截图6、实验分析该滑动窗口协议模拟程序还有进一步完善的余地,例如可以对以下一些地方进行改进:(1)改模拟程序通过命令行来实行,缺少形象直观的界面,希望日后可以设计比较简单明了的界面来展示程序的主要模拟功能。

实验6.滑动协议窗口协议模拟程序修改版

实验6.滑动协议窗口协议模拟程序修改版

实验六滑动窗口协议模拟程序1.实验目的:(1)掌握滑动窗口协议的概念、原理与基本算法。

(2) 理解3种滑动窗口协议:rdt3.0(l位滑动窗口协议)、GBN滑动窗口协议与SR滑动窗口协议。

(3)了解传输层与数据链路层滑动窗口协议的区别与联系,掌握GBN滑动窗口协议的实现原理。

(4) 要求有良好的编程规范与注释信息,要求有详细的说明文档,包括程序的设计思想、活动图、关键问题以及解决方法。

2实验环境(1)linxu(2)局域网能连接Internet3.程序设计的关键问题以及解决方法有哪些?4.简述GBN的实现原理滑动窗口协议也称为Go-Back-N(GBN)协议。

在该协议中,允许发送方传输多个分组(当有多个分组时)而不需等待确认,但它也受限于在流水账中未确认的分组数不能超过最大允许数N。

只有在接收窗口向前滑动时(与此同时也发送了确认),发送窗口才有可能向前滑动。

收发两端的窗口按照以上规律不断地向前滑动,因此这种协议又称为滑动窗口协议。

当发送窗口和接收窗口的大小都等于 1时,就是停止等待协议。

当发送窗口大于1,接收窗口等于1时,就是回退N步协议。

当发送窗口和接收窗口的大小均大于1时,就是选择重发协议。

协议中规定,对于窗口内未经确认的分组需要重传。

这种分组的数量最多可以等于发送窗口的大小,即滑动窗口的大小n减去1(因为发送窗口不可能大于(n-1),起码接收窗口要大于等于1)5.GBN客户端和服务器要处理的事件分别是什么?程序中处理这些事件的机制是什么,具体方法是什么?发送端:network_layer_ready事件。

frame_arrival事件。

timeout事件。

接收端:frame_arrival事件。

cksum_error事件。

ack_timeout事件。

6.描述相关数据结构,并说明其作用7.程序中超时是如何处理的发送方为所发的每个帧设置一个定时器,如果定时器在ACK到达之前超时,则重发此帧。

sendp->timeout=1; 设置8.画出程序流程图9.给出关键代码swpstate1.head=NULL;swpstate1.sendq=sendq_rear=(structsendq_slot*)malloc(sizeof(s tructsendq_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->nex t=NULL; sendq_rear->next=sendp; sendq_rear=sendp; --swpstate1.sws ;swpstate1.lfs=swpstate1.hdr.seqnum;r=swpstate1.hdr.seqnum;do {while(swpstate1.sws>0){ sendp=(struct sendq_slot*)malloc(sizeof(struct sendq_slot)); if(!sendp) exit(1);sendp->msg=swpstate1.lfs+1;sendp->timeout=1;sendp->next=NULL;sendq_rear->next=sendp;sendq_rear=sendp;--swpstate1.sws;++swpstate1.lfs; }swpstate1.hdr.acknum=0;swpstate1.hdr.flags=0;printf("最近收到的ACK的帧序号:%ld\n",r);printf("最近发送的帧序号(发送新帧后):%ld\n",swpstate1.lfs);。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

滑动窗口实验报告(含源码)一、实验目的1.实现一个数据链路层协议的数据传送部分。

2.更好地理解数据链路层协议中的“滑动窗口”技术的基本工作原理。

3.掌握计算机网络协议的基本实现技术。

二、实验要求在一个数据链路层的模拟实现环境中,用C语言实现下两个数据链路层协议。

1.1比特滑动窗口协议2.回退N帧滑动窗口协议三、实验内容充分理解滑动窗口协议,根据滑动窗口协议,模拟滑动窗口协议中发送端的功能,对系统发送的帧进行缓存并加入窗口等待确认,并在超时或者错误时对部分帧进行重传。

编写停等及退回N滑动窗口协议函数,响应系统的发送请求、接收帧消息以及超时消息,并根据滑动窗口协议进行相应处理。

四、源代码及注释#include "sysinclude.h"#include <iostream>using namespace std;extern void SendFRAMEPacket(unsigned char* pData, unsigned int len);//1比特滑动窗口#define WINDOW_SIZE_STOP_WAIT 1//回退N帧协议#define WINDOW_SIZE_BACK_N_FRAME 4//缓存区大小#define BUFFER_SIZE 50typedef enum {DATA,ACK,NAK} Frame_kind;//帧头typedef struct Frame_head{Frame_kind kind;unsigned int seq;unsigned int ack;unsigned char data[100];};//帧typedef struct Frame{Frame_head head;unsigned int size;};//缓存区Frame buffer[BUFFER_SIZE];//当前希望确认的帧,最近缓存的帧,下一次要发送的帧unsigned int expect_frame = 0, last_buffered_frame = 0, next_frame = 0;/** 停等协议测试函数*/int stud_slide_window_stop_and_wait(char *pBuffer, int bufferSize, UINT8 messageType){Frame_head* p = (Frame_head*)pBuffer;//unsigned int frameNum = ntohl(*(unsigned int*)pBuffer);switch (messageType){//网络层要发送一帧数据时case MSG_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 <= WINDOW_SIZE_STOP_WAIT){//发送缓存帧SendFRAMEPacket((unsigned char*)pBuffer, (unsignedint)bufferSize);//窗口上界加1++ next_frame;}return 0;}//物理层收到一帧数据时case MSG_TYPE_RECEIVE : {//解码确认信号unsigned int ack = ntohl(p->ack);//试探for (int i = expect_frame; i < next_frame; ++ i){unsigned int exp_ack = ntohl(buffer[i % BUFFER_SIZE].head.seq);//如果确认消息大于等于期望消息,则说明期望帧已经被确认过了if (ack >= exp_ack){//期望帧+1++ expect_frame;//如果有缓存帧没发出if (next_frame < last_buffered_frame){//发出一个缓存帧SendFRAMEPacket((unsigned char*)(&buffer[next_frame % BUFFER_SIZE]), buffer[next_frame % BUFFER_SIZE].size);//窗口上界+1++ next_frame;}//否则,无法继续发送帧,退出。

等待下次再更新期望确认帧else break;}}return 0;}//超时case MSG_TYPE_TIMEOUT : {//超时重发,把当前窗口内未确认的帧重发一遍for (int i = expect_frame; i < next_frame; ++ i){//if (frameNum > ntohl(buffer[i % BUFFER_SIZE].head.seq)) continue;SendFRAMEPacket((unsigned char*)(&buffer[i % BUFFER_SIZE]), buffer[i % BUFFER_SIZE].size);}return 0;}default : break;}return -1;}/** 回退n帧测试函数*/int stud_slide_window_back_n_frame(char *pBuffer, int bufferSize, UINT8 messageType){Frame_head* p = (Frame_head*)pBuffer;unsigned int timeoutNum = *(unsigned int*)pBuffer;switch (messageType){//网络层要发送一帧数据时case MSG_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 <=WINDOW_SIZE_BACK_N_FRAME){SendFRAMEPacket((unsigned char*)z, (unsigned int)bufferSize);++ next_frame;}return 0;}//物理层接收到一帧数据时case MSG_TYPE_RECEIVE : {unsigned int ack = ntohl(p->ack);cout << "receive ack : " << ack << endl;for (int i = expect_frame; i < next_frame; ++ i){unsigned int exp_ack = ntohl(buffer[i % BUFFER_SIZE].head.seq);cout << "exp_ack : " << exp_ack << endl;if (ack >= exp_ack){++ expect_frame;if (next_frame < last_buffered_frame){SendFRAMEPacket((unsigned char*)(&buffer[next_frame % BUFFER_SIZE]), buffer[next_frame % BUFFER_SIZE].size);++ next_frame;}}else break;}return 0;}//超时case MSG_TYPE_TIMEOUT : {cout << "time out : " << timeoutNum << endl;//超时重发for (int i = expect_frame; i < next_frame; ++ i){unsigned int frameNum = ntohl(buffer[i % BUFFER_SIZE].head.seq);//if (timeoutNum > frameNum) continue;cout << frameNum << endl;SendFRAMEPacket((unsigned char*)(&buffer[i % BUFFER_SIZE]), buffer[i % BUFFER_SIZE].size);}return 0;}default : break;}return -1;}/** 选择性重传测试函数*/int stud_slide_window_choice_frame_resend(char *pBuffer, int bufferSize, UINT8messageType){return 0;}五、思考题1.退回N 帧协议不必像1bit 滑动窗口协议一样,允许发送完一帧后不等确认帧而继续发送,提高了发送效率。

2.缺点是在重传时可能重新传送已经正确发送的数据帧。

相关文档
最新文档