TCP滑动窗口机制
我们可以大概看一下上图的模型:
首先是AB之间三次握手建立TCP连接。在报文的交互过程中,A将自己的缓冲区大小(窗口大小)3发送给B,B同理,这样双方就知道了对端的窗口大小。
A开始发送数据,A连续发送3个单位的数据,因为他知道B的缓冲区大小。在这一波数据发送完后,A就不能再发了,需等待B的确认。
A发送过来的数据逐渐将缓冲区填满。
这时候缓冲区中的一个报文被进程读取,缓冲区有了一个空位,于是B向A发送一个ACK,这个报文中指示窗口大小为1。
A收到B发过来的ACK消息,并且知道B将窗口大小调整为1,因此他只发送了一个单位的数据并且等待B的下一个确认报文。
如此反复。
什么是滑动窗口协议?
一图胜千言,看下面的图。简单解释下,发送和接受方都会维护一个数据帧的序列,这个序列被称作窗口。发送方的窗口大小由接受方确定,目的在于控制发送速 度,以免接受方的缓存不够大,而导致溢出,同时控制流量也可以避免网络拥塞。下面图中的4,5,6号数据帧已经被发送出去,但是未收到关联的 ACK,7,8,9帧则是等待发送。可以看出发送端的窗口大小为6,这是由接受端告知的(事实上必须考虑拥塞窗口cwnd,这里暂且考虑 cwnd>rwnd)。此时如果发送端收到4号ACK,则窗口的左边缘向右收缩,窗口的右边缘则向右扩展,此时窗口就向前“滑动了”,即数据帧10 也可以被发送。
下面就滑动窗口协议做出更详细的说明,这里为了简单起见设定发送方窗口大小为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比特滑动窗口协议?
上面说的只是滑动窗口协议的理论,实际应用中又有不同。首先就是停等协议(stop-and-wait),这时接受方的窗口和发送方的窗口大小都是1,1 个比特就够表示了,所以也叫1比特滑动窗口协议。发送方这时自然发送每次只能发送一个,并且必须等待这个数据包的ACK,才能发送下一个。虽然在效率上比 较低,带宽利用率明显较低,不过在网络环境较差,或是带宽本身很低的情况下,还是适用的。看下面的流程图:
后退n协议?
停等协议虽然实现简单,也能较好的适用恶劣的网络环境,但是显然效率太低。所以有了后退n协议,这也是滑动窗口协议真正的用处,这里发送的窗口大小为n,接受方的窗口仍然为1。具体看下面的图,这里假设n=9:
首先发送方一口气发送10个数据帧,前面两个帧正确返回了,数据帧2出现了错误,这时发送方被迫重新发送2-8这7个帧,接受方也必须丢弃之前接受的3-8这几个帧。
后退n协议的好处无疑是提高了效率,但是一旦网络情况糟糕,则会导致大量数据重发,反而不如上面的停等协议,实际上这是很常见的,具体可以参考TCP拥塞控制。
选择重传协议?
后退n协议的另外一个问题是,当有错误帧出现后,总是要重发该帧之后的所有帧,毫无疑问在网络不是很好的情况下会进一步恶化网络状况,重传协议便是用来解 决这个问题。原理也很简单,接收端总会缓存所有收到的帧,当某个帧出现错误时,只会要求重传这一个帧,只有当某个序号后的所有帧都正确收到后,才会一起提 交给高层应用。重传协议的缺点在于接受端需要更多的缓存。
TCP滑动窗口易错处
前段时间研究分布式时写了一个可扩展的服务器组程序,服务器组之间通信时老是达不到想要的性能。后来抓包排查,原来是TCP滑动窗口引起的问题,本来是很基础的东西,奈何当初没有太在意,导致错误的产生,现在详细写出来,忘不太清楚者警惕!
滑动窗口的基本情况我有必要废话一下。TCP通信为了保证可靠性,每次发送的数据都需要得到对方的ACK才确认对方收到了(仅保证对方TCP接收缓冲收到数据了,但不保证对方应用程序取到数据了),这时如果每次发送一次就要停下来等着对方的ACK消息,显然是一种极大的资源浪费和低下的效率,这时就有了滑动窗口的出现。
发送方的滑动窗口维持着当前发送的帧序号,已发出去帧的计时器,接收方当前的窗口大小(由接收方ACK通知,大体等于接收缓冲大小-未处理的消息包),接收方滑动窗口保存的有已接收的帧信息、期待的下一帧的帧号等,至于滑动窗口的具体工作原理这里就不说了。
一个socket有两个滑动窗口(一个sendbuf、一个recvbuf),两个窗口的大小是通过setsockopt函数设置的,现在问题就出在这里,通过抓包显示,设置的窗口大小没有生效,最后排查发现setsockopt函数是后来加上的,写到了listen函数的后面,这样每次accept出的socket并没有继承得到主socket设置的窗口大小,无语啊……
解决办法:setsockopt函数提前到listen函数之前,这样在服务器程序启动监听前recvbuf就已经有了,accept后的链接得到的就是recvbuf了,启动程序运行,抓包显示窗口已经是指定的大小了。
网络编程其实很简单,任何人都可以写出一套自己的服务器框架,但是细节决定成败,性能的高低有时候就是几个小细节决定的(当然这里说的这个问题是个编程错误,不属于可优化的细节问题)
相关推荐
其中设为1相当于使用后退n帧技术的滑动窗口协议,设为大于1的值则相当于使用选择性重传策略的滑动窗口协议。第2个参数为接收速率设定,编辑框中填入的是接收定时器的间隔时间,单位为ms,1000表示接收速率为每秒处理...
TCP拥塞学习资料,TCP滑动窗口协议,TCP拥塞窗口,网络间对象的传输与调用[new]
采用MFC技术的界面编程,运用C++语言,模拟实现滑动窗口协议。
TCP Sliding Window滑动窗口协议演示动画,Flash播放,可以调整参数
北邮的滑动窗口协议 C源代码清单 int tcp mem schedule struct sock sk int size int kind { int amt TCP PAGES size ; sk >forward alloc + amt TCP MEM QUANTUM; atomic add amt &tcp memory ...
理解数据链路层的滑动窗口协议,完整实现滑动窗口协议中的1bit滑动窗口协议,通过socket实现TCP连接来进行模拟
计算机网络 课程设计 滑动窗口协议模拟 java 小程序实现计算机网络 课程设计 滑动窗口协议模拟 java 小程序实现
生成树协议及TCP滑动窗口演示,很形象。flash小动画
为方便起见,使用了STL,使用时注意全局变量在不同函数中尽量不要重复。代码为GBK编码
udt.sdk.3.3,UDP的可靠传输项目UDT(开源),采用了类似TCP的滑动窗口协议,在 udt.sdk.3.2 的基础上作了改进,使适用于网格计算.
SND.UNA :是个绝对指针,它指向的是已发送但未收到确认的第个字节的序列号,也就是 #2 的第个字节。SND.NXT :也是个绝对指针,它指向未发送但可发送
开发环境vs2005,开发语言:c语言 基于windows开发的多线程案例,多线程方式实现了TCP协议的滑动窗口协议及选择重传协议 希望对研究多线程编程的童鞋有所帮助
要实现无差错的传输数据,我们可以采用重发请求(ARQ)协议,它又可分为连续ARQ协议、选择重发ARQ协议、滑动窗口协议。本文重点介绍滑动窗口协议,其它的两种有兴趣的可参考相关的网络通信之类的书。 采用滑动...
UDP滑动窗口协议是一种适用于现代...文中论述了基于 UDP的滑动窗口协议并给出了实现方 法,通过测试分析,该协议有效地解决了 TCP的高协议处理开销和 UDP的低可靠性之间的矛盾,而 CPU占用率比单独采用 UDP只增加约3%。
20.3 滑动窗口 212 20.4 窗口大小 214 20.5 PUSH标志 215 20.6 慢启动 216 20.7 成块数据的吞吐量 218 20.7.1 带宽时延乘积 220 20.7.2 拥塞 220 20.8 紧急方式 221 20.9 小结 224 第21章 TCP的超时与重传 226 21.1 ...
(自己公司同事写的PPT) TCP/IP协议栈的历史 TCP/IP协议栈的设计思想 IP协议 UDP协议 TCP协议,状态机 TCP定时器,滑动窗口
TCP重传 滑动窗口 流量控制 拥塞控制 330-371
p164 - p198 TCP重传 滑动窗口 流量控制 拥塞控制
老外编写的TCP协议的纯C实现,经典推荐想要学习网络协议的朋友
TCP协议是面向连接的协议,负责把信息...为实现TCP数据包可靠传输,TCP协议利用滑动窗口进行流量,利用慢开始、拥塞避免、快重传和快恢复四种算法实现拥塞控制,并通过差错控制来确保数据包正确的到达另一方应用程序。