TCP 协议中的 Window Size与吞吐量

时间:2022-01-20 06:30:22

TCP协议中影响实际业务流量的参数很多,这里主要分析一下窗口的影响。

?TCP窗口目的

为了获得最优的连接速率,使用TCP窗口来控制流速率(flow control),滑动窗口就是一种主要的机制。这个窗口允许源端在给定连接传送数据分段而不用等待目标端返回ACK,一句话描述:窗口的大小决定在不需要对端响应(acknowledgement)情况下传送数据的数量。?官方定义:“The amount of octets that can be transmitted without receiving an acknowledgement from the other side”。

TCP窗口机制

??TCP header中有一个Window Size字段,它其实是指接收端的窗口,即接收窗口,用来告知发送端自己所能接收的数据量,从而达到一部分流控的目的。其实TCP在整个发送过程中,也在度量当前的网络状态,目的是为了维持一个健康稳定的发送过程,比如拥塞控制。因此,数据是在某些机制的控制下进行传输的,就是窗口机制。发送端的发送窗口是基于接收端的接收窗口来计算的,也就是我们常说的TCP是有连接的发送,数据传输需要对端确认,发送的数据分为如下四类来看

窗口滑动发送数据

(1)已经发送并且对端确认(Sent/ACKed)---------------发送窗外 缓冲区外

(2)已经发送但未收到确认数据(Sent/UnACKed)----- --发送窗内 缓冲区内?

(3)允许发送但尚未防的数据?(Unsent/Inside)-----------发送窗内 缓冲区内?

(4)未发送暂不允许(Unsent/Outside)-------------------发送窗外 缓冲区内?

TCP窗口就是这样逐渐滑动,发送新的数据,滑动的依据就是发送数据已经收到ACK,确认对端收到,才能继续窗口滑动发送新的数据。可以看到窗口大小对于吞吐量有着重要影响,同时ACK响应与系统延时又密切相关。需要说明的是:如果发送端的窗口过大会引起接收端关闭窗口,处理不过来反之,如果窗口设置较小,结果就是不能充分利用带宽,所以仔细调节窗口对于适应不同延迟和带宽要求的系统很重要

TCP窗口大小

最早TCP协议涉及用来大范围网络传输时候,其实是没有超过56Kb/s的?连接速度的。因此,TCP包头中只保留了16bit用来标识窗口大小,允许的最大缓存大小不超过64KB。为了打破这一限制,RFC1323规定了TCP窗口尺寸选择,是在TCP连接开始的时候三步握手的时候协商的(SYN, SYN-ACK,ACK),会协商一个  Window size scaling factor,之后交互数据中的是Window size value,所以最终的窗口大小是二者的乘积.

Window size value: 64 or 0000 0000 0100 0000 (16 bits) 

?Window size scaling factor: 256 or 2 ^ 8 (as advertised by the 1st packet) 

The actual window size is 16,384 (64 * 256)

这里的窗口大小就意味着,直到发送16384个字节,才会停止等待对方的ACK.随着双方回话继续,窗口的大小可以修改window size value 参数完成变窄或变宽,但是注意:Window size scaling factor乘积因子?必须保持不变。在RFC1323中规定的偏移(shift count)是14,也就是说最大的窗口可以达到Gbit,很大。

Wireshark抓包实例

这一机制并不总是默认开启的和系统有关,貌似Linux默认开启,Windows默认关闭。

?TCP窗口的参数设置

TCP窗口起着控制流量的作用,实际使用时这是一个双端协调的过程,还涉及到TCP的慢启动?(Rapid Increase/Multiplicative Decrease),拥塞避免,拥塞窗口和拥塞控制。可以记住,发送速率是由min(拥塞窗口,接收窗口),接收窗口在下文有讲。

TCP窗口优化设置?

TCP?窗口既然那么重要,那要怎么设置,一个简单的原则是2倍的BDP.这里的BDP的意思是bandwidth-delay product,也就是带宽和时延的乘积,带宽对于网络取最差连接的带宽。

buffer size = 2 * bandwidth * delay?

还有一种简单的方式,使用ping来计算网络的环回时延(RTT),然后表达为:

buffer size = bandwidth * RTT?

?为什么是2倍?因为可以这么想,如果滑动窗口是bandwidth*delay,当发送一次数据最后一个字节刚到时,对端要回ACK才能继续发送,就需要等待一次单向时延的时间,所以当是2倍时,刚好就能在等ACK的时间继续发送数据,等收到ACK时数据刚好发送完成,这样就提高了效率。

举个例子:带宽是20Mbps,通过ping我们计算单向时延是20ms,那么可以计算:20000000bps*8*0.02 = 52,428bytes?,因此我们最优窗口用 104,856 bytes = 2 x 52,428,所以说当发送者发送104,856 bytes数据后才需要等待一个ACK响应,当发送了一半的时候,对端已经收到并且返回ACK(理想情况),等到ACK回来,又把剩下的一半发送出去了,所以发送端就无需等待ACK返回。

发现了么?这里的窗口已经明显大于64KB了,所以机制改善了,上一级。

TCP窗口流量控制?