滑动窗口实验
滑动窗口算法基本原理与实践
滑动窗⼝算法基本原理与实践学过计算机⽹络的同学,都知道滑动窗⼝协议(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。
可以⽤来解决⼀些查找满⾜⼀定条件的连续区间的性质(长度等)的问题。
由于区间连续,因此当区间发⽣变化时,可以通过旧有的计算结果对搜索空间进⾏剪枝,这样便减少了重复计算,降低了时间复杂度。
[VIP专享]滑动窗口协议实验SWP
-2-
2006年经省农业厅,南平市政府19批41准年,毛南泽平东农在校《与改建造阳我农们业的工学程习学》校一合文署中办,学把,这强句强原联指合治,学实态行度一的套话班古子为,今两用个,校从区哲的学管的理高体度制做,了从新而的使分学析校,的深办化学了规对模实,事办求学是实的力理都解有,长并足为的其发提历展出史,了的逐一经步个验发经教展典训成的告为注诉有释我着,们广指:泛出什发:么展“时空‘候间实坚和事持良’实好就事发是求展客是前观,景存党的在和闽着国北的家唯一的一切事一事业所物就集,会文第‘顺理一是利、个’发农问就展工题是;商,客什实贸实观么事为事事时求一求物候是体是的背是,地内离一面看部实个向待联事老全我系求话国们,是题招的即,,生学规党实和校律和事就。性国求业职,家是的业‘的一,教求事一语办育’业、,学明就就实出规显是会事自模不我遭求东最同们遇是汉大于去挫地班、高研折看固师等究。待所资教”同学著力育。时校《量和毛,、汉最中泽只学书雄学东有生河厚教对坚和间、育中持学献办,国实校王学不社事当传质同会求前》量点、是工。和就中,作书办在国党以中学于革和及称声职命人存赞誉业的民在刘高教分的的德的育析事问“综所无业题修合有不才学性工贯能好国作穿顺古家和着利,级任实前实重何事进事点事求,求中情是一是专都的旦。和必精背”省须神离其级靠。实意文自因事思明己而求是学完他是根校成才就据。。能必实而找然事这到遭求些中到索成国挫真绩革折理的命甚。取的至得规倒是律退得,。益制实于定事学出求校适是党合是政中马领国克导国思的情主坚的义强路世领线界导方观,针的得政根益策本于,要全指求体导,党中是员国马干革克部命思和走主教向义职胜的工利精的,髓辛实。勤事工求作是和是共中同国努革力命的实结践果经,验但的最高主度要总的结一和条概是括得,益中于国学革校命始和终建坚设持的实经事验求表是明的,原实则事,求可是以是说胜,利坚之持本实,事只求要是坚原持则实是事我求们是学,校我各们项党事就业会健永康远、立稳于定不和败谐之发地展。的重要保证。
计算机网络--滑动窗口实验报告
计算机网络--滑动窗口实验报告计算机网络滑动窗口协议实验报告目录一、实验内容和实验环境描述(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()从物理层发送和接收一帧。
滑动窗口协议实验报告
滑动窗⼝协议实验报告竭诚为您提供优质⽂档/双击可除滑动窗⼝协议实验报告篇⼀:实验⼆滑动窗⼝协议实验报告2<滑动窗⼝协议的模拟>项⽬设计报告作者:完成⽇期:签收⼈:签收⽇期:1需求分析实验⽬的:加深对滑动窗⼝协议的理解实验任务:实现对于滑动窗⼝协议的模拟实验环境:pc机操作系统:windowsxp开发环境:microsoftVisualc++6.0,可以使⽤mFc类库1.1问题重述界⾯要求:项⽬要求的所有功能应可视,要有简单的界⾯。
由⼀台pc(或线程)向另⼀台pc(或线程)发送数据包时,界⾯应显⽰出双⽅帧个数的变化,帧序号,发送和接受速度,暂停或重传提⽰等,界⾯中必须动态显⽰数据帧的发送和接受情况,包括在相应的窗⼝详细显⽰相应的AcK和其他收发数据帧后发出的消息,以表明模拟协议的正确运作过程。
在各种情况下,接受⽅和发送⽅窗⼝应实时显⽰帧的发送和接受情况,包括序号,时间戳,内容等。
以及窗⼝的填充和清空情况。
⽹络接⼝要求:两台机器或是⼀台机器中两个独⽴的线程模拟发送⽅与接受⽅,接收数据的端⼝初始应为监听状态。
发送⽅向接受⽅发起连接,成功后开始发送数据。
接受⽅要求:接受⽅应由固定⼤⼩的滑动窗⼝,并对收到信息缓存。
当发送⽅速度过快或帧丢失(超时),接受⽅应发送消息,要求暂停或是重传(停---等协议)。
接受⽅要求按序向⽹络层提交收到的帧。
发送⽅要求:发送⽅发送速度可以调节,并可以暂停或是重发。
发送⽅重传时可仅重传需要的帧。
可指定滑动窗⼝数⽬和要发送的帧的总数,停等的超时时间间隔以及发送类型(正常发送,错序发送,以及缺帧,丢帧的现象),发送速率等参数。
2概要设计2.1原理概述发送⽅和接受⽅都维持了⼀个窗⼝,窗⼝内部包含了那些可以接受的序列号。
发送⽅的窗⼝⼤⼩从0开始,以后可以增⼤到某⼀个预设的最⼤值。
由于发送⽅可能在将来的某个时刻重传未被确认的帧,所以它必须把已经送出去的帧保留⼀段时间,直到他知道接受⽅已经接受了这些帧。
滑动窗口协议实验报告
滑动窗口协议实验报告1. 引言滑动窗口协议是计算机网络中用于实现可靠数据传输的一种协议。
其核心思想是使用一个窗口来管理发送方和接收方之间的数据传输进程,通过滑动窗口的机制来实现流量控制和错误恢复。
本实验旨在通过编写滑动窗口协议的模拟程序,深入理解该协议的工作原理及其在数据传输中的应用。
2. 实验环境本次实验采用C++语言进行编程,并在Windows操作系统下进行测试。
3. 实验过程3.1 窗口大小的确定首先,我们需要确定滑动窗口的大小。
在实际应用中,窗口大小需要根据网络状况来调整,以保证传输效率。
本次实验中,我们设置窗口大小为5。
3.2 发送方逻辑实现发送方负责将数据分割为若干个数据包,并发送给接收方。
发送方需要维护发送窗口的起始位置和结束位置,在每次发送数据包后,将发送窗口向前滑动一格。
如果接收窗口收到接收方的确认信息,发送方将收到确认的数据包从发送窗口中移除,并将窗口向前滑动一格。
3.3 接收方逻辑实现接收方需要维护接收窗口的起始位置和结束位置。
当接收窗口收到数据包时,接收方首先检查数据包的顺序是否正确,如果顺序正确,则将数据包保存并发送确认信息给发送方。
接收方随后将接收窗口向前滑动一格,等待下一个数据包的到来。
3.4 测试与验证在实验过程中,我们通过模拟网络传输的延迟、丢包等情况来验证滑动窗口协议的可靠性。
通过调整滑动窗口的大小以及模拟网络传输的不同情况,我们可以观察到滑动窗口协议在不同场景下的性能表现。
4. 实验结果分析通过实验,我们观察到滑动窗口协议在正常网络传输情况下,能够实现高效的数据传输。
当网络传输出现延迟或丢包时,滑动窗口协议能够通过重传机制和流量控制策略,确保数据的可靠传输。
在窗口大小适当的情况下,滑动窗口协议能够最大化利用网络带宽,提高数据传输的效率。
5. 实验总结本次实验通过编写模拟程序,深入理解了滑动窗口协议的工作原理及其在数据传输中的应用。
滑动窗口协议通过窗口的滑动机制,实现了对数据传输过程的控制和管理,从而保证了数据的可靠性和传输效率。
时序滑动窗口评估方法
时序滑动窗口评估方法时序滑动窗口评估方法,也被称为滚动交叉验证,是一种用于评估时序数据模型性能的方法。
在时序数据中,每个数据点的观测值与前面的观测值相关联,这种相关性需要在模型评估过程中得到有效处理。
时序滑动窗口评估方法通过模拟真实预测环境,将训练集和测试集划分为连续时间窗口,以便更准确地评估模型的性能。
以下是时序滑动窗口评估方法的基本原理及步骤:1.数据预处理:将原始时序数据按照时间顺序进行排序,并进行必要的数据清洗和特征工程。
确保数据的质量和合理性。
2.定义时间窗口:确定时间窗口的大小和间隔。
时间窗口的大小决定了每个训练和测试集的样本数量,时间窗口的间隔决定了预测的时间跨度。
3.划分训练集和测试集:根据时间窗口的大小和间隔,将数据划分为多个连续的训练集和测试集。
通常情况下,训练集和测试集之间是有重叠的。
4.建立模型:使用训练集来训练模型。
可以选择适合时序数据的模型,例如ARIMA模型、LSTM网络等。
根据实际情况决定模型的复杂度。
5.模型评估:使用测试集来评估模型的性能。
在每个时间窗口中,使用训练集来训练模型,并使用测试集来进行预测。
计算预测结果与真实值之间的误差,例如均方根误差(RMSE)、平均绝对误差(MAE)等。
6.性能指标计算:对于每个时间窗口,可以计算各种性能指标,例如平均误差、方差、相关系数等。
可以将这些指标的平均值作为模型整体性能的评估指标。
7.结果分析:根据评估指标和实际需求,分析模型的性能。
如果模型表现良好,则可以使用该模型进行预测。
如果模型表现不佳,则需要调整模型参数或者尝试其他模型。
在实际应用中,时序滑动窗口评估方法可以用于评估各种时序数据模型,例如股票价格预测、天气预报、销售预测等。
通过合理选择时间窗口的大小和间隔,可以更准确地评估模型的性能,并提供对未来数据的可靠预测。
总之,时序滑动窗口评估方法是一种针对时序数据的有效评估方法。
在实际应用中,根据具体问题的需求,可以灵活调整时间窗口的大小和间隔,并结合合适的模型来评估和预测时序数据的性能。
实验一 滑动窗口协议实验
实验一滑动窗口协议实验◆实验目的:在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及选择重传三种协议,它们的差别仅在于各自窗口尺寸的大小不同而已。
计算机网络实验 (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地址,看看是否和源地址一致。
实验一 滑动窗口协议实验
实验一滑动窗口协议实验◆实验目的:在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实验任务对实际系统中的协议分层和协议软件的设计与实现有基本的认识。
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两种配置。
滑动窗口协议实验报告
滑动窗口协议实验报告篇一:实验二滑动窗口协议实验报告2<滑动窗口协议的模拟>项目设计报告作者:完成日期:签收人:签收日期:1 需求分析实验目的:加深对滑动窗口协议的理解实验任务:实现对于滑动窗口协议的模拟实验环境:PC机操作系统:Windows XP开发环境:Microsoft Visual C++ ,可以使用MFC类库问题重述界面要求:项目要求的所有功能应可视,要有简单的界面。
由一台PC(或线程)向另一台PC (或线程)发送数据包时,界面应显示出双方帧个数的变化,帧序号,发送和接受速度,暂停或重传提示等,界面中必须动态显示数据帧的发送和接受情况,包括在相应的窗口详细显示相应的ACK和其他收发数据帧后发出的消息,以表明模拟协议的正确运作过程。
在各种情况下,接受方和发送方窗口应实时显示帧的发送和接受情况,包括序号,时间戳,内容等。
以及窗口的填充和清空情况。
网络接口要求:两台机器或是一台机器中两个独立的线程模拟发送方与接受方,接收数据的端口初始应为监听状态。
发送方向接受方发起连接,成功后开始发送数据。
接受方要求:接受方应由固定大小的滑动窗口,并对收到信息缓存。
当发送方速度过快或帧丢失(超时),接受方应发送消息,要求暂停或是重传(停---等协议)。
接受方要求按序向网络层提交收到的帧。
发送方要求:发送方发送速度可以调节,并可以暂停或是重发。
发送方重传时可仅重传需要的帧。
可指定滑动窗口数目和要发送的帧的总数,停等的超时时间间隔以及发送类型(正常发送,错序发送,以及缺帧,丢帧的现象),发送速率等参数。
2 概要设计原理概述发送方和接受方都维持了一个窗口,窗口内部包含了那些可以接受的序列号。
发送方的窗口大小从0开始,以后可以增大到某一个预设的最大值。
由于发送方可能在将来的某个时刻重传未被确认的帧,所以它必须把已经送出去的帧保留一段时间,直到他知道接受方已经接受了这些帧。
当第n帧的确认到来时,第n-1,第n-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)改模拟程序通过命令行来实行,缺少形象直观的界面,希望日后可以设计比较简单明了的界面来展示程序的主要模拟功能。
滑动窗口算法基本原理
滑动窗口算法基本原理滑动窗口算法,这个名字听上去有点高深,其实就像你在超市里推着购物车,一边逛一边把需要的东西放进去,简单得不要不要的。
想象一下,你走进超市,目标是买到一个完整的购物清单。
你在每个货架前停下,看看是不是需要的东西,然后把它们放进车里。
可问题来了,车子装得太满了,推着真是累。
于是你开始思考,如何合理地选择,才能让购物车既不满到倾倒,又能装下你所有想要的东西。
这个时候,你就是在使用滑动窗口算法。
这个算法可不仅仅是在超市里使用,其实它在计算机科学里大显身手,处理数据的时候也能发挥奇效。
比如说,想要找出一个字符串里的所有子串,特别是那些有特殊性质的子串。
通常这种事情挺麻烦,脑袋里得过一遍又一遍,结果很可能让你晕头转向。
可是,滑动窗口算法就像你的好朋友,轻轻一推,让你少走很多弯路。
你只需要不断调整你的“窗口”,在字符串上滑来滑去,轻松就能找到你想要的结果。
说到这里,咱们再来细说一下,什么是“窗口”。
在滑动窗口算法中,窗口其实就是一段范围,比如在字符串中,它可以是一个字符到另一个字符的距离。
你想找的东西就在这个范围内。
想象一下你在看电影,镜头一移动,你就能看到不同的场景。
这个窗口可以大可以小,完全取决于你想要的结果。
你也可以把它当成一扇窗,往外看,只不过窗外的景色是数据。
你从这一边看过去,发现那一边的美好,回过头来,你会觉得这也太神奇了!咱们聊聊这个算法的使用场景。
无论是字符串处理、数组求和,还是更复杂的动态规划问题,滑动窗口都能派上用场。
想象一下,你在处理一串数据,想找出其中的最大值或最小值,脑子里转了无数个圈,结果就是一团糟。
这个时候,滑动窗口就像你的超能力,能够迅速找到那道闪亮的光。
比如,你有一串数字,想找出其中和最大的连续子数组,滑动窗口来帮忙,直接调整窗口的大小,问题就迎刃而解。
使用滑动窗口算法时,也得注意不要用力过猛。
适当的控制窗口大小很重要,不然就容易出现“过犹不及”的情况。
比方说,你把窗口开得太大,结果啥都看不清楚;反之,如果窗口太小,可能就会漏掉一些关键的信息。
opencv滑动窗口原理
opencv滑动窗口原理一、概述滑动窗口原理是计算机视觉和图像处理领域中一种常用的技术,广泛应用于边缘检测、特征提取、目标跟踪等领域。
OpenCV是一款广泛使用的计算机视觉库,其中包含了大量的滑动窗口算法的实现。
本篇文章将详细介绍滑动窗口原理的基本概念、实现方式以及在OpenCV中的应用。
二、滑动窗口原理滑动窗口原理的基本思想是在图像中选取一个固定大小的区域(窗口),然后围绕这个区域进行滑动,不断调整窗口的位置,从而获取图像中的不同区域的信息。
通过这种方式,可以实现对图像的局部特征的检测和提取。
在滑动窗口过程中,可以通过比较窗口内像素值与周围像素值的关系,来确定窗口内是否存在特定特征。
常用的特征包括边缘、纹理、颜色等。
通过对窗口内像素值进行统计、滤波等处理,可以提取出这些特征,从而实现相应的目标检测、识别和跟踪任务。
OpenCV提供了多种滑动窗口算法的实现,如Sobel边缘检测、Harris角点检测、LoG滤波器等。
这些算法在OpenCV中以函数的形式提供,用户可以通过调用相应的函数来实现滑动窗口原理的应用。
在实现滑动窗口算法时,需要注意窗口大小、滑动步长、比较阈值等参数的选择。
这些参数需要根据具体的应用场景和需求进行调整,以达到最佳的效果。
此外,还需要考虑窗口滑动过程中的边界效应和噪声干扰等问题,通过适当的滤波和处理方法来加以解决。
四、应用场景滑动窗口原理在计算机视觉和图像处理领域有着广泛的应用。
以下是一些常见的应用场景:1.边缘检测:通过滑动窗口算法可以检测图像中的边缘信息,从而实现目标区域的定位和识别。
2.特征提取:滑动窗口算法可以用于提取图像中的纹理、颜色等特征,用于分类、识别和跟踪任务。
3.目标跟踪:通过滑动窗口算法可以实时跟踪图像中的目标对象,实现运动分析和行为识别。
4.医学影像分析:滑动窗口算法可以用于医学影像的病灶检测和病理分析。
五、总结滑动窗口原理是一种常用的计算机视觉和图像处理技术,通过在图像中选取固定大小的区域,并围绕这个区域进行滑动,可以实现对图像的局部特征的检测和提取。
滑动窗口实验报告
实验目的:了解滑动窗口技术的原理和应用,通过实验验证滑动窗口在信号处理、图像处理和文本分析等领域的有效性。
实验环境:操作系统: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. 实验结果实验结果表明,经过滑动窗口处理后的信号相对于原始信号更加平滑,噪声干扰得到了有效抑制。
2分钟了解卷积的滑动窗口实现过程
2分钟了解卷积的滑动窗⼝实现过程1介绍sliding window (滑动窗⼝) 在深度学习中得到了极其⼴泛的运⽤。
从卷积层到池化层,都能看见它的⾝影。
2卷积操作如下图,在⼆维图像上,下⾯显⽰了其中⼀个通道的像素集合,卷积就是将滤波器(F11、F12、F21、F22)在图像上滑动,对应位置相乘求和得到卷积的结果,假如⼀张3×3的特征图,经过2×2的卷积操作后,会得到⼀张2×2的特征图。
】卷积操作当输⼊为多维图像(或者多通道特征图)时,多通道卷积如下图所⽰(图⽚来⾃链接),图中输⼊图像尺⼨为6×6,通道数为3,卷积核有2个,每个尺⼨为3×3,通道数为3(与输⼊图像通道数⼀致),卷积时,仍是以滑动窗⼝的形式,从左⾄右,从上⾄下,3个通道的对应位置相乘求和,输出结果为2张4×4的特征图。
⼀般地,当输⼊为m×n×c时,每个卷积核为k×k×c,即每个卷积核的通道数应与输⼊的通道数相同(因为多通道需同时卷积),输出的特征图数量与卷积核数量⼀致。
多维图像的卷积对应卷积运算过程(对应位置相乘,再相加)如下图。
卷积操作3卷积的滑动窗⼝实现过程假设对象检测算法输⼊⼀个 14×14×3 的图像,在这⾥如果#滤波#器(卷积核)⼤⼩为 5×5,数量是 16个, 14×14×3 的图像在过滤器处理(卷积)之后映射为 10×10×16的特征图。
然后通过 2×2的最⼤池化操作,图像减⼩到 5×5×16。
然后添加⼀个连接 400 个单元的全连接层,接着再添加⼀个全连接层,最后通过 softmax 单元输出。
这⾥⽤ 4 个数字来表⽰y,它们分别对应 softmax 单元所输出的 4 个类别出现的概率。
这 4 个类别可以是⾏⼈、汽车、摩托车和背景或其它对象(预先设定)。
【算法】滑动窗口
【算法】滑动窗⼝滑动窗⼝1.概念滑动窗⼝是⼀类很常见的题型,最常见的就是⼦串问题,因为滑动窗⼝是⼀个连续的,所以很容易就是问满⾜条件的最⼤或者最⼩⼦串啊,这个条件就是不同的地⽅,但万变不离其宗,滑动窗⼝就是⼀个窗⼝的移动。
总之:⼦串+最值 --> 滑动窗⼝滑动窗⼝有两⼤类固定长度的滑动窗⼝:窗⼝的⼤⼩是固定好的,这是其实分为了窗⼝形成和⼈窗⼝滑动两个过程,窗⼝形成就是要先让窗⼝达到要求的长度;窗⼝滑动的过程在右边界长的时候,左边界也要跟着长,维持窗⼝长度不变;可变长度的滑动窗⼝:这也是遇到最多的,控制窗⼝移动的原因不是长度,⽽是是否达到题⽬中某⼀条件,如果达到此条件,那右边界停下,左边界开始移动,试图去破坏这⼀条件,就是在这个过程中不断的更新结果。
2.过程1.从题⽬中先整理出条件,常见的⽐如说⼦序列的和⼤于某值,⼦串中包含某些值,⼦串中出现了重复值,先把这些条件找出来,这就是⽤来移动窗⼝的依据;2.初始化left和right指针都为0,right指针从头⾛到尾,当不满⾜上⾯的条件时,right⾛,⼀直⾛到这个窗⼝满⾜上⾯我们总结出来的条件了,停下;3.记录下我们要的答案,⽐如最典型的问⼦串的最⼩长度啊啥的,记录下这时候我们的right-left+1,这就是⽬前窗⼝的⼤⼩;4.右边⾛不动了那左边就得开始⾛了,移动左指针,每次移动都要把左指针的值给去除,因为我们统计的结果只能是窗⼝⾥的结果,出去了⾃然就不要了,然后,每⼀次左指针的移动都要判断是否满⾜条件,⽐如要求⼦串和⼤于某⼀值,左边移动⼀步,减去这个值看还⼤于⽬标值吗,如果满⾜,更新我们最终要的最⼩⼦串,因为这时候⼦串长度肯定缩⼩了嘛,直到不满⾜条件为⽌;如果不满⾜,那左指针不⽤再动了,右指针可以开始动了,寻找下⼀个满⾜条件时停下来。
5.就这样重复,右边动完左边动,左边动完右边再动;总结:右边界要使窗⼝达到某⼀条件,左边界使窗⼝跳出这⼀条件。
滑动窗快速算法研究
相比滑动窗DFT算法,基于格雷码核的滑动窗CS-SCHT算法分别可 节省约37%的运算时间,且在自适应滤波中的应用,可获得更高的 信噪比。这些探索内容为滑动窗CS-SCHT算法在信号、图像处理 等领域作为DFT的替代提供了重要的实验依据。
滑动窗快速算法研究
滑动窗算法是离散正交变换的短时快速算法,该类算法利用重叠 滑动的时域窗口截取连续的离散信号,并利用上一个窗口信号的 是处理非平稳信号的一种有效方法。
论文主要致力于广泛应用的傅立叶相关滑动窗变换及应用研究。 针对滑动窗傅立叶变换,本文提出了二维多点滑动DFT算法。
当滑动的点数多于一点时,提出的算法比其它傅里叶相关的算法 具有更低的计算复杂度。论文尝试将提出的二维多点滑动DFT算 法应用于图像篡改盲检验之中,进一步提出了基于二维多点滑动 DFT的图像篡改混合检测算法。
实验结果表明该检测算法在检测速度和检测准确率之间取得了 较好的均衡。本文还深入研究了滑动窗CS-SCHT算法,实现了基 于格雷码核(GCK)的滑动窗CS-SCHT算法。
实验三:滑动窗口协议的实现
实验三滑动窗口协议的实现实验目的理解滑动窗口协议对连续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的接收提示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机通信网络实验滑动窗口实验学院:班级:学号:姓名:2012年11月14日一、实验目的实现一个滑动窗口协议的数据传送部分,目的在于使学生更好地理解基本滑动窗口协议的基本工作原理,掌握计算机网络协议的基本实现技术。
二、原理简介(1)窗口机制滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。
发送窗口和接收窗口的序号的上下界不一定要一样,甚至大小也可以不同。
不同的滑动窗口协议窗口大小一般不同。
发送方窗口内的序列号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧。
(2)1比特滑动窗口协议当发送窗口和接收窗口的大小固定为1时,滑动窗口协议退化为停等协议(stop-and-wait)。
该协议规定发送方每发送一帧后就要停下来,等待接收方已正确接收的确认(acknowledgement)返回后才能继续发送下一帧。
由于接收方需要判断接收到的帧是新发的帧还是重新发送的帧,因此发送方要为每一个帧加一个序号。
由于停等协议规定只有一帧完全发送成功后才能发送新的帧,因而只用一比特来编号就够了。
(3)后退n协议由于停等协议要为每一个帧进行确认后才继续发送下一帧,大大降低了信道利用率,因此又提出了后退n协议。
后退n协议中,发送方在发完一个数据帧后,不停下来等待应答帧,而是连续发送若干个数据帧,即使在连续发送过程中收到了接收方发来的应答帧,也可以继续发送,且发送方在每发送完一个数据帧时都要设置超时定时器,只要在所设置的超时时间内仍收到确认帧,就要重发相应的数据帧。
如:当发送方发送了N个帧后,若发现该N帧的前一个帧在计时器超时后仍未返回其确认信息,则该帧被判为出错或丢失,此时发送方就不得不重新发送出错帧及其后的N帧。
三、实验步骤1.编写滑动窗口协议的实现程序;2.在模拟实现,调试并运行自己编写的协议实现程序;3.了解协议的工作轨迹,如出现异常情况,在实验报告中写出原因分析。
四、实验过程1、程序功能及设计思路功能概述:用客户端/服务器模式代表A站、B站。
先由客户端输入服务器IP地址,然后客户端和服务器之间建立连接。
在服务器中可以自行设置发送窗口的大小(如果需要实现的是停等式协议,那么就将发送窗口设为1),设置完后,服务器开始向客户端根据滑动窗口(停等式)的协议规定发送数据帧,同时启动计时器,客户端收到数据帧后马上向服务器发送确认帧,服务器如果没有及时收到客户端的确认帧,就要返回到出错的地方进行重发。
实现滑动窗口协议的算法:发送端:1、socket初始化,绑定端口,监听,接受连接;2、设置发送窗口大小winsize;3、启动定时器,设置时间为0.2s*winsize;4、组帧并发送数据,即设置序号SN、数据data、长度msglen,之后发送一个窗口中的帧,每发送一个数据SN++;若发送完毕,则执行第6步;5、接收确认帧,每收到一个正确的确认帧,则改变滑动窗口上下限,若正确接收所有确认帧,则关闭定时器,返回第3步;若接收超时或有确认帧丢失,则SN=right_number,返回第3步;6、关闭socket,重新建立新的进程,等待下一个连接,返回第2步。
接收端:1、socket初始化,连接服务器;2、接收数据帧,将data存入缓存recvBuf,RN=SN+1;3、发送确认帧,若接收完毕,则关闭socket,否则返回第二步。
实现停等式协议的算法:和上述滑动窗口协议的算法类似,只需在发送端的第二步中将发送窗口大小winsize设置为1即可。
2、C语言程序代码:客户端Client://*********************** receiver.c ***************************** #pragma comment(lib, "ws2_32.lib") //WINSOCK API连接库文件#include <winsock.h> //WINSOCK API的头文件,需要包含在项目中#include <stdio.h>#include<string.h>int err;SOCKET sockClient; //用于客户端的SocketSOCKADDR_IN addrSrv; //服务端地址SOCKADDR_IN addrClient; //客户端地址char serverip[20]; //服务端IP// int i=0; //testint length = sizeof(struct sockaddr);int RN=0; //接收序号char recvBuf[10][100]; //发送帧测试内容,10条//---------------------------------------------------------------struct dataFrame //数据帧{int SN; //发送序号char data[100];int msglen; //字符长度,采用长度计数的组帧技术};struct dataFrame dframe;//************************ 初始化****************************** void initialization(){WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD( 1, 1 ); //WinSocket1.1版本err = WSAStartup( wVersionRequested, &wsaData );//wsaData用来存储系统传回的关于WinSocket的资料if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ){WSACleanup( );}return;}//***************** 连接服务器***********************void connecting(){printf("input server IP:");scanf("%s",serverip); //输入服务器ipaddrSrv.sin_addr.S_un.S_addr=inet_addr(serverip); //设置服务器地址addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000); // 设置端口号err=connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//连接服务器}//************************ 接收数据帧******************************void receiveFrame(){recv(sockClient,(char*)&dframe,sizeof(dframe),0); //接受数据strcpy(recvBuf[dframe.SN],dframe.data);printf("----------接收第%d号帧-------------\n",dframe.SN);RN=dframe.SN+1;//if(RN==2)Sleep(600); //用于测试//if(RN==2 && i==0){i++;return;} //用于测试send(sockClient,(char*)&RN,sizeof(RN),0); //发送希望接收到的数据编号}//************************main函数******************************** void main(){int i;initialization(); //初始化阶段,若返回值err=0,则表示初始化成功if(err!=0){printf("Intialization failed.\n");return;}sockClient=socket(AF_INET,SOCK_STREAM,0); //建立socket,SOCK_STREAM为遵从TCP/IP协议的socketif(sockClient==-1){printf("Building a socket failed.\n");return;}connecting(); //和发送端建立连接if(err!=0) //若返回值err=0,则表示建立连接成功{printf("connecting failed.\n");return;}else{printf("-------got connection from server.-------\n");}while (1) //循环接受数据{receiveFrame();//接收数据if(RN==10) //判断是否已接收完,本次测试一共为10帧数据帧{closesocket(sockClient); //关闭连接printf("-------close the socket.-------\n");break;}}printf("\n接收到的数据如下:\n");for(i=0;i<10;i++) //将接收的数据打印出来{printf("%s\n",recvBuf[i]);}while(1);WSACleanup();}//********************** end of program ************************服务器Server://*********************** server.c ***************************** #pragma comment(lib, "ws2_32.lib") //WINSOCK API连接库文件#include <winsock.h> //WINSOCK API的头文件,需要包含在项目中#include <stdio.h>#include<string.h>#include <stdlib.h>#include <windows.h>#pragma comment(lib,"Winmm.lib")int err;SOCKET sock; //用于服务器监听的SocketSOCKADDR_IN addrSrv; //服务端地址SOCKADDR_IN addrClient; //客户端地址int winsize; //滑动窗口大小int min,max;int length = sizeof(struct sockaddr);int RN; //接收序号int right_number=0; //已正确发送数据帧的计数器char sendBuf[10][100]={"Whether 60 or 16,","there is in every human being’s heart the lure of wonder,","the unfailing childlike appetite of what’s next and the joy of the game of living.", "so long as it receives messages of beauty, hope, cheer, courage","and power from men and from the Infinite, so long are you young.","When the aerials are down,","and your spirit is covered with snows of cynicism","and the ice of pessimism, then you are grown old, even at 20,","but as long as your aerials are up, to catch waves of optimism,","there is hope you may die young at 80."}; //发送帧测试内容,10条//---------------------------------------------------------------struct dataFrame //数据帧{int SN; //发送序号char data[100];int msglen; //字符长度,采用长度计数的组帧技术};struct dataFrame dframe;//************************ 初始化****************************** void initialization(){WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD( 1, 1 ); //WinSocket1.1版本err = WSAStartup( wVersionRequested, &wsaData );//wsaData用来存储系统传回的关于WinSocket的资料if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ){ WSACleanup( );}return;}//************************ 绑定端口****************************** void bindport(){addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//设置服务器地址,INADDR_ANY表示使用自己的IP地址addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000); //设定端口为6000err=bind(sock,(LPSOCKADDR)&addrSrv,sizeof(SOCKADDR));return;}//************************ 重发数据帧***************************** int resend(){err=10;dframe.SN=right_number;printf("超时,未收到第%d的确认帧,现重新发送...\n",right_number); return 0;}//************************ 发送数据帧***************************** int SendFrame(SOCKET*socketConn){UINT wTimerRes=200*winsize; //定义时间间隔为0.5sUINT wAccuracy=0; //定义分辨率UINT TimerID;dframe.SN=0;while(1){TimerID=timeSetEvent(wTimerRes,wAccuracy,(LPTIMECALLBACK)resend,(DWORD)(1), TIME_ONESHOT);while(dframe.SN>=min && dframe.SN<=max && dframe.SN<10){strcpy(dframe.data,sendBuf[dframe.SN]);dframe.msglen=strlen(sendBuf[dframe.SN]);send(*socketConn,(char*)&dframe,sizeof(struct dataFrame),0);//发送消息到客户端dframe.SN++;}while(1) //接受收端的确认帧{recv(*socketConn,(char*)&RN,sizeof(RN),0);if(err==10){timeKillEvent(TimerID);err=0;break;}if(right_number==RN-1){printf("收到第%d帧的确认帧...\n",RN-1);min=RN; //改变滑动窗口上下限max=min+winsize-1;right_number++;}else if(right_number<RN-1){printf("第%d帧丢失,现重发...\n",right_number);timeKillEvent(TimerID);dframe.SN=right_number;break;}if(right_number==dframe.SN){timeKillEvent(TimerID);break;}}if(RN==10) return 0;}}//线程函数用于处理一个客户端请求DWORD WINAPI ConnectClient(LPVOID socketConn){printf("input the size of slide window:");scanf("%d",&winsize);min=0;max=winsize-1;SendFrame(socketConn);printf("--------all message is delivered successful.---------\n\n");closesocket(*((SOCKET*)socketConn)); //关闭Socketprintf("--------disconnect with %s.---------\n\n",inet_ntoa(addrClient.sin_addr)); return 0;}void main(){HANDLE hThread;//线程句柄DWORD threadId;initialization(); //初始化阶段,若返回值err=0,则表示初始化成功if(err!=0){printf("Intialization failed.\n");return;}sock=socket(AF_INET,SOCK_STREAM,0);//建立socket,SOCK_STREAM为遵从TCP/IP协议的socketif(sock==-1){printf("Building a socket failed.\n");return;}bindport(); //绑定端口if(err!=0){printf("Binding a socket failed.\n");return;}if(listen(sock,5)==-1)//使服务器端的Socket进入监听状态,并设定可以建立的最大连接数为5 {printf("listening failed.\n");return;}printf("--------------------server waitting.--------------------\n");while (1) //循环等待请求{ SOCKET *socketConn =(SOCKET *)malloc(sizeof(SOCKET));//用于与客户端连接的socket*socketConn = accept(sock,(struct sockaddr*)&addrClient,&length);printf("connectingwith %s\n-------------------------------\n",inet_ntoa(addrClient.sin_addr));//开辟线程处理一个客户端请求hThread =CreateThread(NULL,0,ConnectClient,(LPVOID)socketConn,0,&threadId);}closesocket(sock);WSACleanup();system("pause");}3、实验结果1)停等式协议的测试在没有传输错误情况下,设置发送窗口为1,接收窗口也为1,在dos界面显示传递的整个过程,其中Server的IP为: 222.25.162.196 ,Client的IP为:222.25.162.5。