TCP的流量控制和拥塞控制
流量控制:
所谓流量控制,主要是接收方传递信息给发送方,使其不要发送数据太快,是一种端到端的控制。主要的方式就是返回的ACK中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据
这里面涉及到一种情况,如果B已经告诉A自己的缓冲区已满,于是A停止发送数据;等待一段时间后,B的缓冲区出现了富余,于是给A发送报文告诉A我的rwnd大小为400,但是这个报文不幸丢失了,于是就出现A等待B的通知||B等待A发送数据的死锁状态。为了处理这种问题,TCP引入了持续计时器(Persistence timer),当A收到对方的零窗口通知时,就启用该计时器,时间到则发送一个1字节的探测报文,对方会在此时回应自身的接收窗口大小,如果结果仍未0,则重设持续计时器,继续等待。
传递效率
一个显而易见的问题是:单个发送字节单个确认,和窗口有一个空余即通知发送方发送一个字节,无疑增加了网络中的许多不必要的报文(请想想为了一个字节数据而添加的40字节头部吧!),所以我们的原则是尽可能一次多发送几个字节,或者窗口空余较多的时候通知发送方一次发送多个字节。对于前者我们广泛使用Nagle算法,即:
1. 若发送应用进程要把发送的数据逐个字节地送到TCP的发送缓存,则发送方就把第一个数据字节先发送出去,把后面的字节先缓存起来;
2. 当发送方收到第一个字节的确认后(也得到了网络情况和对方的接收窗口大小),再把缓冲区的剩余字节组成合适大小的报文发送出去;
3. 当到达的数据已达到发送窗口大小的一半或以达到报文段的最大长度时,就立即发送一个报文段;
对于后者我们往往的做法是让接收方等待一段时间,或者接收方获得足够的空间容纳一个报文段或者等到接受缓存有一半空闲的时候,再通知发送方发送数据。
拥塞
在计算机网络中的链路容量(带宽),交换节点中的缓存和处理机等,都是网络的资源。在某段时间,网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏,这种情况叫做拥塞。
拥塞控制与流量控制密切相关,所谓拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或者链路不致过载,拥塞控制的前提是:网络能够承受现有的网络负荷,是一个全局性的过程。流量控制往往指点对点通信量的控制,是端到端的问题,流量控制所要做的就是抑制发送端发送数据的速率,以便接收端可以接收。
几种拥塞控制的方法
1.慢开始和拥塞避免
发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地变化。发送方让自己的发送窗口等于拥塞窗口。
在发送数据中,发送方根据收到的确认报文,来判断网络的拥塞情况,在网络没有拥塞的情况下,拥塞窗口就会增大一些,以便把更多分组发送出去,如果网络阻塞,拥塞窗口就减少一点。
慢开始算法的核心是从小到大逐渐增大拥塞窗口数值。通常在刚开始发送报文段时,先把拥塞窗体设置为一个最大报文段MSS的数值,而在每收到对上一轮报文段(,每次加倍后的报文段的个数,可能不止一个报文段)的确认后,就把拥塞窗体的数值加倍。
为了防止拥塞窗口cwnd增长过大而引起网络拥塞,还设置了一个慢开始门限ssthresh状态变量。
当cwnd<ssthresh时,使用上述慢开始算法
当cwnd>ssthresh时,停止使用慢开始算法,改用拥塞避免算法
当cwnd=ssthresh时,可以使用慢开始算法,也可以使用拥塞避免算法
拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,而不是成倍增大,每经过一个往返时间就把发送方的拥塞窗口cwnd加一,拥塞窗口cwnd按线性规律缓慢增加。
无论在慢开始阶段还是拥塞避免阶段,只要发送方判断出现了网络拥塞,就把慢开始门限ssthresh设置为出现拥塞时的发送窗口的一半,然后把拥塞窗口重新设置为1,执行慢开始算法。 这样可以迅速减少主机发送到网络中的分组数,使发生拥塞的路由器有足够的时间处理挤压分组。
2.快重传和快恢复
快重传算法首先要求接收方每收到一个失序的报文段后就马上发出反复确认(反复发送对前面有序部分的确认),而不是等待自己发送数据时才进行稍待确认,也不是累积收到的报文发送累积确认,假设发送方连续收到三个反复确认,就应该马上重传对方未收到的报文段(有收到反复确认,说明后面的报文段都送达了,仅仅有中间丢失的报文段没送达)。
快恢复算法与快重传算法配合使用,其过程有例如以下两个要点:
1、当发送方连续收到三个反复确认时,就把慢开始门限减半,这是为了预防网络发生拥塞。注意,接下来不运行慢开始算法。
2、因为发送方认为网络很可能没有发生堵塞(假设发生了严重堵塞的话,就不会一连有好几个报文段到达接收方,就不会导致接收方连续发送反复确认),因此与慢开始不同之处是现在不执行慢开始算法(即拥塞窗体的值不设为1个MSS),而是把拥塞窗体的值设为慢开始门限减半后的值,而后开始执行拥塞避免算法,线性地增大拥塞窗体
如图:
在数据传输中,我们还要考虑接收方的情况,发送方发送窗口的大小由网络的拥塞程度来决定,接收方的缓存空间是有限的,接收方会根据自己的接受能力设定接受窗口rwnd,它会把这个窗口值写入TCP首部的窗口字段,传送给发送方,因此,从接收方对发送方的流量控制的角度考虑,发送窗口一定不能超过接受窗口rwnd。
发送窗口的上限值 = Min[rwnd,cwnd]