一:滑动窗口
首先看下TCP的头部结构,里面有个窗口大小的选项,占位2个字节,说明滑动窗口最大的发送大小为 65535(2^16 - 1)字节,也就是64K,当前也可以通过选项字段进行放大.
tcp发包是通过对方设置的滑动窗口控制发包的速率,如上,1-4表示已经发送并确认的包,5-7表示已经发送,但是对方未确认的,8-11,表示准备发送的,12-15表示还未发送,滑动窗口的范围仅仅是5-11。
例如:发送5-7的包,发送时,会将5-7的包拷贝一份放入重传缓冲区,开启定时器重传(此处的重传是个慢重传,比如第一次间隔200ms,第二次400ms,第三次800ms,是幂次方增长),对端收到了5,7包,6包未收到,这个时候会发送一个5包的确认,这个时候收到确认包后,会把5包的重传数据清空,并且删除对应的定时发送,对6,7包进行重传,若后面再收到8包,然后再收到6包,这个时候会发送一个8包的确认,这种叫累计确认。
从上面的实例可以看出tcp包的确认是按照最小序列号进行确认的,这种是默认情况,要是在丢包率比较高的场景,使用TCP可以开启sack选项,这样就会对每一个包进行确认,而不是确认包序列号的最小值,对每一个包确认后,只需要重传没有确认的包,在上面的示例场景中,就会对5,7包确认,这样重传就只需要重传6, 7包就不会被重传
二:拥塞控制
拥塞控制主要是为了防止发送方发的太快,使得网络来不及处理,从而导致网络拥塞,主要分为慢开始、.拥塞控制、.快重传、.快恢复四个阶段
1.慢开始
发送方维护一个拥塞窗口cwnd,初始为1,发送一个包,收到确认cwnd+1,经过一个RTT,cwnd = cwnd*2
2.拥塞控制
cwnd也不是无限增长的,有一个ssthresh阈值,当cwnd大于等于ssthresh时,每经过一个RTT则cwnd=cwnd+1,而不是成倍增长了
3.快重传
当收到一个失序报文时,马上发送确认消息,比如数据包1,2,3 ,4 当收到1,2,4的时候,没有收到3,这个时候不能去4进行确认,这个时候马上发送一个2的确认包,告诉对方发送3包过来,当对方连续收到三个2包的确认ack的时候,会马上发送3包,而不是等待3包的定时器重传(此处的重传是滑动窗口的慢重传)
4.快恢复
当收到连续三个重复确认的报文时,就执行快恢复把ssthresh减半,cwnd也置为ssthresh/2,而不是上图的直接把cwnd置为1
三:拥塞控制跟滑动窗口的区别
主要是针对的对象不一样,拥塞控制是为了防止网络拥塞,滑动窗口是预防对端接收不及时