1.重传
1.1 超时重传
两个情况:
a 数据包丢失
b ack应答丢失
RTT:网络包往返的时间(不是一个定值)
RTO:超时重传的时间间隔(也是一个动态的)
RTO设置的时间长:浪费时间资源,效率低下
RTO时间短:对面ACK还没传回来,就已经进行重传了,导致网络堵塞,导致更多ack回不来
所以,RTO的时间大小应该略大于RTT的时间大小
如果超时重发的数据,再次超时的时候,又需要重传的时候,TCP 的策略是超时间隔加倍 。
也就是每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送。
1.2 快速重传
快速重传不以时间驱动,以数据驱动。其核心概念就是:收到三次相同的ACK就会触发快速重传
有个问题就是:快速重传是重传一个还是那一个ack后面的所有?传一个效率低,传所有做无用功有重复。
但是快速重传比超时重传有效率吧。
1.3 SACK方法 [ 选择性确认 ]
就是在TCP头部加一个sack信息,这个信息可以记录接收到了哪些编号的数据。当然,这个带sack的tcp是由接受方发送的。
这个也是发送方接收到三个重复的ACK后才进行重传。
1.4 duplicate SACK
D-sack:就是在sack的基础上还可以告诉发送方发送了重复数据
这个方法可以让发送方知道自己重传的原因是1)网络包没发过去2)还是对面ack没发过来
但是我不知道这个有什么用。。。。
2.滑动窗口
接受窗口应该和发送窗口差不多大
3.流量控制
原因:如果发送方一直不停的发送数据,接受方处理不过来,不能及时发送ack回去,发送方又会开始重传,更加浪费网络资源。
所以需要一种,实时的能控制发送方发送出去的数据刚好能让接受方处理完的方法。
3.1 缓冲区和窗口的关系
缓冲区其实包含窗口
有一种严重的情况就是当接受方处理不过来,减少缓冲区时里面还有没有读取的数据,就会造成数据丢失的严重情况
所以,TCP不允许同时缩小窗口和缓冲区,正确的做法应该是:先缩小窗口,一段时间后再缩小缓冲区。
3.2 窗口关闭
一个很严重的死锁情况:
窗口关闭又打开后,ack报文丢失,就会造成死锁
解决方法就是:在收到零窗口的ack后启动计时器,定期发送探测报文,询问对方是否已经解除零窗口。
窗口探测的次数一般为 3 次,每次大约 30-60 秒(不同的实现可能会不一样)。如果 3 次过后接收窗口还是 0 的话,有的 TCP 实现就会发 RST 报文来中断连接。
3.3 糊涂窗口综合症(哈哈哈
可能发生在接受方和发送方,就是这时候可用窗口非常小,只能发送几字节的数据(光IP和TCP头加起来就已经是40字节了)
这时候要做两件事:
1.让接受方不通告小窗口:
2.让发送方避免发送小数据: