TCP 滑动窗口和 拥塞窗口 |
您所在的位置:网站首页 › 滑动窗口示意图怎么做图片 › TCP 滑动窗口和 拥塞窗口 |
转http://coolshell.cn/articles/11609.html
滑动窗口 -- 表征发送端和接收端的接收能力 拥塞窗口-- 表征中间设备的传输能力 TCP滑动窗口 需要说明一下,如果你不了解TCP的滑动窗口这个事,你等于不了解TCP协议。我们都知道,TCP必需要解决的可靠传输以及包乱序(reordering)的问题,所以,TCP必需要知道网络实际的数据处理带宽或是数据处理速度,这样才不会引起网络拥塞,导致丢包。 所以,TCP引入了一些技术和设计来做网络流控,Sliding Window是其中一个技术。 前面我们说过,TCP头里有一个字段叫Window,又叫Advertised-Window,这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。 为了说明滑动窗口,我们需要先看一下TCP缓冲区的一些数据结构: 上图中,我们可以看到: 接收端LastByteRead指向了TCP缓冲区中读到的位置,NextByteExpected指向的地方是收到的连续包的最后一个位置,LastByteRcved指向的是收到的包的最后一个位置,我们可以看到中间有些数据还没有到达,所以有数据空白区。 发送端的LastByteAcked指向了被接收端Ack过的位置(表示成功发送确认),LastByteSent表示发出去了,但还没有收到成功确认的Ack,LastByteWritten指向的是上层应用正在写的地方。于是: 接收端在给发送端回ACK中会汇报自己的AdvertisedWindow = MaxRcvBuffer – LastByteRcvd – 1; 而发送方会根据这个窗口来控制发送数据的大小,以保证接收方可以处理。下面我们来看一下发送方的滑动窗口示意图: (图片来源) 上图中分成了四个部分,分别是:(其中那个黑模型就是滑动窗口) #1已收到ack确认的数据。 #2发还没收到ack的。 #3在窗口中还没有发出的(接收方还有空间)。 #4窗口以外的数据(接收方没空间)下面是个滑动后的示意图(收到36的ack,并发出了46-51的字节): 下面我们来看一个接受端控制发送端的图示:
TCP的拥塞处理 – Congestion Handling 上面我们知道了,TCP通过Sliding Window来做流控(Flow Control),但是TCP觉得这还不够,因为Sliding Window需要依赖于连接的发送端和接收端,其并不知道网络中间发生了什么。TCP的设计者觉得,一个伟大而牛逼的协议仅仅做到流控并不够,因为流控只是网络模型4层以上的事,TCP的还应该更聪明地知道整个网络上的事。 具体一点,我们知道TCP通过一个timer采样了RTT并计算RTO,但是,如果网络上的延时突然增加,那么,TCP对这个事做出的应对只有重传数据,但是,重传会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,于是,这个情况就会进入恶性循环被不断地放大。试想一下,如果一个网络内有成千上万的TCP连接都这么行事,那么马上就会形成“网络风暴”,TCP这个协议就会拖垮整个网络。这是一个灾难。 所以,TCP不能忽略网络上发生的事情,而无脑地一个劲地重发数据,对网络造成更大的伤害。对此TCP的设计理念是:TCP不是一个自私的协议,当拥塞发生的时候,要做自我牺牲。就像交通阻塞一样,每个车都应该把路让出来,而不要再去抢路了。 关于拥塞控制的论文请参看《Congestion Avoidance and Control》(PDF) 拥塞控制主要是四个算法:1)慢启动,2)拥塞避免,3)拥塞发生,4)快速恢复。这四个算法不是一天都搞出来的,这个四算法的发展经历了很多时间,到今天都还在优化中。 备注: 1988年,TCP-Tahoe 提出了1)慢启动,2)拥塞避免,3)拥塞发生时的快速重传 1990年,TCP Reno 在Tahoe的基础上增加了4)快速恢复 慢热启动算法 – Slow Start首先,我们来看一下TCP的慢热启动。慢启动的意思是,刚刚加入网络的连接,一点一点地提速,不要一上来就像那些特权车一样霸道地把路占满。新同学上高速还是要慢一点,不要把已经在高速上的秩序给搞乱了。 慢启动的算法如下(cwnd全称Congestion Window): 1)连接建好的开始先初始化cwnd = 1,表明可以传一个MSS大小的数据。 2)每当收到一个ACK,cwnd++; 呈线性上升 3)每当过了一个RTT,cwnd = cwnd*2; 呈指数让升 4)还有一个ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法”(后面会说这个算法) 所以,我们可以看到,如果网速很快的话,ACK也会返回得快,RTT也会短,那么,这个慢启动就一点也不慢。下图说明了这个过程。 这里,我需要提一下的是一篇Google的论文《An Argument for Increasing TCP’s Initial Congestion Window》Linux 3.0后采用了这篇论文的建议——把cwnd 初始化成了 10个MSS。 而Linux 3.0以前,比如2.6,Linux采用了RFC3390,cwnd是跟MSS的值来变的,如果MSS< 1095,则cwnd = 4;如果MSS>2190,则cwnd=2;其它情况下,则是3。 拥塞避免算法 – Congestion Avoidance前面说过,还有一个ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法”。一般来说ssthresh的值是65535,单位是字节,当cwnd达到这个值时后,算法如下: 1)收到一个ACK时,cwnd = cwnd + 1/cwnd 2)当每过一个RTT时,cwnd = cwnd + 1 这样就可以避免增长过快导致网络拥塞,慢慢的增加调整到网络的最佳值。很明显,是一个线性上升的算法。 拥塞状态时的算法前面我们说过,当丢包的时候,会有两种情况: 1)等到RTO超时,重传数据包。TCP认为这种情况太糟糕,反应也很强烈。 sshthresh = cwnd /2 cwnd 重置为 1 进入慢启动过程2)Fast Retransmit算法,也就是在收到3个duplicate ACK时就开启重传,而不用等到RTO超时。 TCP Tahoe的实现和RTO超时一样。 TCP Reno的实现是: cwnd = cwnd /2 sshthresh = cwnd 进入快速恢复算法——Fast Recovery上面我们可以看到RTO超时后,sshthresh会变成cwnd的一半,这意味着,如果cwnd |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |