重传机制
TCP实现可靠传输的方式之一,是通过序列号与确认应答
在TCP当中,当发送端的数据达到接受主机时,接收端主机会接受一个确认应答,表示已收到消息
TCP针对数据包丢失的情况,会用重传机制解决:
- 超时重传
- 快速重传
- SACK
- D-SACK
超时重传
重传机制的其中一个方式,就是在发送数据的时候,设定一个定时器,当超过指定的时间后,没有收到对方的ACK确认应答报文,就会重发该数据,也就是我们常说的超时重传
TCP会在以下两种情况发生超时重传:
- 数据包丢失
- 确认应答丢失
超时时间应该设置为多少呢? RTT(Round-Trip Time 往返时延):就是数据从网络一端传送到另一端所需的时间,也就是包的往返时间
超时重传时间是以RTO(Retransmission Timeout 超时重传时间)表示。
超时重传时间RTO的值应该略大于报文往返RTT的值。
实际上【报文往返RTT的值】是经常变化的,因为我们的网络也是时常变化的。也就是因为【报文往返RTT的值】是经常波动的,所以【超时重传时间RTO的值】应该是一个动态变化的值。
估计往返时间,通常需要采样以下两个:
- 需要TCP通过采样RTT的时间,然后加权平均,算出一个平滑RTT的值,而且这个值还要不断的变化,因为网络状况在不断地变化
- 除了采样RTT,还要采样RTT的波动范围,这样就避免了RTT如果有一个大的波动的话,很难被发现的情况
快速重传
TCP还有l另外一种快速重传(Fast Retransmission)机制,它不以时间为驱动,而是以数据为驱动重传。
快速重传的工作方式是应当收到三个相同的ACK报文时,会在定时器过期之前,重传丢失的报文段。
快速重传机制只解决了一个问题,就是超时时间的问题,但是它依然面临着另外一个问题。就是重传的时候,是重传之前的一个,还是重传所有的报文段的问题。
根据TCP的不同实现,以上两种情况都有可能实现。为了解决不知道该重传哪些TCP报文,于是就有了SACK方法。
SACK
还有一种实现重传的机制j叫:SACK(Selective Acknowledgement选择性确认)。
这种方式需要在TCP头部【选项】字段里加一个SACK的东西。它可以将缓存的地图发送给发送方,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。
D-SACK
Duplicate SACK,其主要使用了SACK来告诉【发送方】哪些数据被重复接受了