主要的考虑还是要区分包的丢失是由于链路故障还是乱序等其他因素引发。
两次duplicated ACK时很可能是乱序造成的!三次duplicated ACK时很可能是丢包造成的!四次duplicated ACK更更更可能是丢包造成的,但是这样的响应策略太慢。丢包肯定会造成三次duplicated ACK!综上是 选择收到三个重复确认时窗口减半效果最好,这是实践经验。
在没有fast retransmit / recovery 算法之前,重传依靠发送方的retransmit timeout,就是在timeout内如果没 有接收到对方的ACK,默认包丢了,发送方就重传,包的丢失原因:
1)包checksum 出错
2)网络拥塞
3)网络断,包括路由重收敛,但是发送方无法判断是哪一种情况,于是采用最笨的办法,就是将自己 的发送速率减半,即CWND 减为1/2,这样的方法对2是有效的,可以缓解网络拥塞,3则无所谓,反正 网络断了,无论发快发慢都会被丢;但对于1来说,丢包是因为偶尔的出错引起,一丢包就对半减速不 合理。
于是有了fast retransmit 算法,基于在反向还可以接收到ACK,可以认为网络并没有断,否则也接收不到 ACK,如果在timeout 时间内没有接收到> 2 的duplicated ACK,则概率大事件为乱序,乱序无需重传, 接收方会进行排序工作;
而如果接收到三个或三个以上的duplicated ACK,则大概率是丢包,可以逻辑推理,发送方可以接收 ACK,则网络是通的,可能是1、2造成的,先不降速,重传一次,如果接收到正确的ACK,则一切 OK,流速依然(包出错被丢)。
而如果依然接收到duplicated ACK,则认为是网络拥塞造成的,此时降速则比较合理。