TCP滑动窗口、拥塞控制原理
滑动窗口
滑动窗口的定义
1.“窗口”对应的是一段可以被发送的字节序列,其连续的范围称为窗口;
2.“滑动”则是指这段“允许发送的范围”是可以随着发送的过程而变化的,方式就是按顺序“滑动”。
滑动窗口的作用
是一种流量控制方法,该协议允许发送方在停止等待确认前可以连续发送发个分组。由于发送方不必每发送一个分组就停下来等待确认,因此该协议可以加速数据的传输。
基本概念
1、 TCP协议的两端分别是发送者A和接受者B,由于是全双工通讯的,因此A and B应该同时维护着一个独立的发送缓冲区和接受缓冲区,由于对等性,我们以A发送B接受的情况作为例子;
2、 发送窗口是发送缓存的一部分,是可以被TCP协议发送的那部分,其实应用层需要发送的所有数据都被放进了发送者的发送缓冲区了;当接收方确认数据后,这个滑动窗口不时地向右移动。窗口两个边沿的相对运动增加或减少了窗口的大小。
3、 发送窗口相关的四个概念:已发送并收到确认的数据(不再发送窗口和发送缓冲区之内);已发送但未收到确认的数据(位于发送窗口之中);允许发送但尚未发送的数据以及发送窗口外发送缓冲区内暂时不需要发送的数据。
4、 每次成功发送数据之后,发送窗口就会在发送缓冲区中按顺序移动,将新的数据包含到窗口中准备发送。
滑动窗口的几个特点
1.发送方不必发送一个全窗口大小的数据。
2.来自接收方的一个报文段确认数据并把窗口向右滑动,这是因为窗口的大小是相对于确认序号的。
3.正如从报文段7到8中的变化那样,窗口的大小可以减小,但是窗口的右边沿却不能向左移动。
4.接收方在发送一个ACK前不必等待窗口被填满。在前面可以得知许多实现每收到两个报文段就会发送一个ACK。
流量控制
流量控制的主要有两个重要的点要掌握。一 是TCP利用滑动窗口来实现流量控制机制; 二 是考虑流量控制中的传输效率。
流量控制
所谓的流量控制,主要是接收方传递信息给发送方,使其不要发送数据太快,而是一种端到端的控制。
主要的控制方法:接收窗口通过返回的ACK,其中会包含自己的接受窗口的大小,并且利用大小来控制发送方的数据发送:
这里面涉及到一种情况,如果B已经告诉A自己的缓冲区已满,于是A停止发送数据;等一段时间后,B的缓冲区出现了富余,于是发送报文告诉A我的RWND大小为400,但是这个报文不幸丢失了,于是就出现了A等待B的通知 || B等待A发送数据的死锁状态。
为了解决这个问题,TCP引入了持续计时器(Persistence timer)当A收到对方的零窗口通知时,就启动该计时器,时间到则发送一个字节的探测报文,对方会在此时回应自身的接受窗口的大小,如果结果仍为0,则重设持续计时器(更新),继续等待。
传递效率解决
一个显而易见的问题是:单个发送字节单个确认,和窗口有一个空余即通知发送方发送一个字节,这无疑增加了网络中的许多不必要的报文(如果为了一个字节的数据而添加的40个字节的头部吧!),所以我们的原则是尽可能一次多发几个字节,或者窗口空余较多的时候通知发送方一次多发送几个字节。对于前者我们广泛使用Nagle算法,即:
*1 若发送应用进程要把发送的数据逐个字节地送到TCP的发送缓存,则发送方就要把第一个数据字节先发送出去,把后面的字节先缓存起来;
*2 当发送方收到第一个字节的确认后(也得到了网络情况和对方的接受窗口的大小),在把缓冲区的剩余字节组成合适大小的报文发送出去;
*3 当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段;
后者我们往往是通过让接收方等待一段时间,或者接受方获得足够的空间,或者接收方获得足够的空间容纳一个报文段或者等到接受缓存有一半空闲的时候,再通知发送发发送数据
拥塞控制
网络中的链路容量和交换结点中的缓存和处理机都有着工作的极限,当网络的需求超过他们的工作极限时,就出现了拥塞。拥塞控制就是为了防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。
常用的方法
-1 慢启动,拥塞控制
-2 快重传,快恢复
一切的基础还是慢启动开始,方法思路:
*1 发送方维持一个叫做“拥塞窗口”的变量,该变量和接受端口共同决定了发送者的发送窗口;
*2 当主机开始发送数据时,避免一下子将大量的字节注入到网络中,造成或者增加拥塞,选择发送一个 1字节的试探报文;
*3 当接收到第一个字节的数据的确认后,就发送两个字节的报文;
*4 若再次收到两个字节的报文段的确认,则发送4个字节,依次递增2的指数级;
*5 最后到达一个提前设定的“ 慢启动门限 ”ssthresh(慢启动阈值),比如24,即一次发送了24个分组,此时遵循下面的条件判断:
①CWND < ssthresh ,继续使用慢启动算法;
②CWND > ssthresh , 停止使用慢启动算法,改用拥塞避免算法;
③CWND = ssthresh ,即两种算法都可以使用。
所谓的拥塞避免算法:就是每经过一个往返时间RTT就把发送方的拥塞窗口 +1,即让拥塞窗口缓慢增大,按线性规律增长;
当出现网络拥塞时,比如丢包时,将慢启动门限设置为原来的一半,然后将cwnd设置为1,然后执行慢启动算法(起点较低,指数级增长)
上述方法的目的是在拥塞发生时循序减少 主机发送到网络中的分组数,使得发送拥塞的路由器有足够的时间去把队列中积压的分组处理完毕。
慢启动和拥塞控制算法常常作为一个整体使用,而快重传和快恢复则是为了减少因为拥塞导致的数据包丢失带来的重传时间,从而避免了传递无用的数据到网路。
快重传机制
1 当接受方建立这样的机制,如果一个包丢失,则对后续的包继续发送针对该包的重传请求
2 一旦发送方接收到三个一样的确认,就知道该包之后出现了错误,立刻重传该包;
3 此时发送方执行“快恢复”算法:①慢启动门限减半②CWND设为慢开始门限减半后的数值③执行拥塞避免算法(高起点,线性增长)
TCP的Window是一个16bit位字段,它代表的是窗口的字节容量,也就是TCP标准窗口最大为2^16 -1 = 65535个字节。
另外在TCP的选项字段中还包括了一个TCP窗口扩大因子,option-kind 为 3 ,option-length为 3 个字节,option-data取值范围 0 -14.窗口扩大因子用来扩大TCP窗口,可把原来16bit的窗口,扩大为31bit