TCP重传、滑动窗口、流量控制、拥塞控制

TCP重传机制

1、超时重传:数据包丢/ACK丢时就会触发超时重传。

2、快速重传:解决超时重发的时间等待。当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段。(问题:重传时是重传一个还是重传所有)

3、SACK:选择性确认。在TCP头「选项」字段里加个 SACK ,它可以将已收到的数据信息发送给「发送方」,这样发送方就可以知道哪些数据收到哪些数据没收,只重传丢失的数据

4、D-SACK:用SACK告诉「发送方」有哪些数据被重复接收(可让发送方知道是发出去的包丢了还是接收方回应 ACK 丢了;可知道是不是发送方的包被网络延迟了;可知道网络中是不是把发送方的包给复制了)

滑动窗口

发一次数据等一个ACK,包的往返时间越长通信效率越低。可通过指定窗口大小,在设置窗口大小内无需等待ACK而继续发送数据。

流量控制

如果一直无脑发数据但对方处理不来,就导致触发重发机制从而导致网络流量的无端浪费。TCP 提供一种机制让「发送方」根据「接收方」的实际接收能力控制发送的数据量,通过让接收方指明希望从发送方接收的数据大小(窗口大小)来进行流量控制。

窗口关闭:窗口大小为 0 时就会阻止发送方给接收方传递数据直到窗口变为非 0 为止。接收方向发送方通告窗口大小时通过 ACK 报文通告,发生窗口关闭时,接收方处理完数据后会向发送方通告一个窗口非 0 的 ACK ,如果这个ACK在网络中丢失,会导致发送方一直等待接收方的非 0 窗口通知,接收方也一直等待发送方的数据,造成死锁。

解决:TCP 为每个连接设一个持续定时器,只要 TCP 连接一方收到对方的零窗口通知就启动持续计时器。超时就会发送窗口探测报文(3次),而对方在确认这个探测报文时,给出自己现在的接收窗口大小(为0就重新启动持续计时器;不是0那死锁局面就可打破了;3次后接收窗口还是0就发RST报文中断连接)

拥塞控制

避免「发送方」数据填满整个网络。只要发送方没在规定时间内接收到 ACK ,也就是发生了超时重传,就会认为网络出现了拥塞。只要网络中没有出现拥塞,拥塞窗口就会增大;出现拥塞就减少。

慢启动(指数增长):一点点提高发送数据包的数量,发送方每收到一个 ACK,拥塞窗口 大小++。有个叫慢启动门限的状态变量(拥塞窗口大小<门限:用慢启动;否则使用拥塞避免算法)

拥塞避免(线性增长):每收到一个 ACK,拥塞窗口增加1/拥塞窗口大小。一直增长后网络慢慢进入拥塞状况,出现丢包现象,触发重传机制,进入「拥塞发生算法」

拥塞发生:超时重传(慢启动门限设为拥塞窗口大小/2,拥塞窗口大小重置为初始化值ss -nli可查看)、快速重传(拥塞窗口大小设为原来一半,慢启动门限设为拥塞窗口大小,然后进入快速回复算法)当接收方发现丢了一个中间包时发送三次前一个包的ACK,于是发送端会快速重传不必等待超时再传

快速恢复:拥塞窗口= 慢启动门限 + 3( 确认有3个数据包被收到),重传丢失数据包,如果再收到重复 ACK,那拥塞窗口++;如果收到新数据 ACK ,把 拥塞窗口 设置为第一步中 慢启动门限 值(原因是该 ACK 确认了新数据,说明数据已收到,该恢复过程已结束,可以回到恢复前的状态了,也即再次进入拥塞避免状态)