1.什么是重传

好比我从淘宝买东西,商家通过快递向我发送货物,但货物可能在快递途中弄丢了,我反馈给商家货物没收到后,商家给补发一个货物,这就是重传。

商家怎么知道货物丢了呢?可能是我的反馈,也可能是快递公司的反馈,或是商家发现我没确认收货。这些方式就是ACK,SACK,RACK,NACK等报文了。怎么理解这些报文呢?下面从三种传输方式来解释重传的原理和工作方式。

2.TCP的重传机制

ACK:acknowledgement应答,响应。在TCP里的ACK是一种累积ACK,当前n个数据块收到后,接收端发送ACKn+1,告知发送端前n个数据收到了,而不是发一块数据给一个ACK响应。

假如从A到B送d1,d2,d3,d4,d5,d6,d7七块数据:

其中d3,d4丢失了,

那么ACK就是这样的:

B收到d2后,ACK3,表明收到了d1,d2。

B收到d5后,ACK3,因为没收到d3,无法累积,还停留在游标3。

B收到d6,d7后,还是ACK3,同上。

什么时候会重传d3,d4呢?

2.1超时重传

A每发送完一块数据d后,会将其加入超时重传队列,当收到ACK3后,将d1,d2从队列移出,当d3-d7的计时T到达后,就会开始对其进行重传。

2.2快速重传

收到了3个ACK3,A就可以判定d3没收到了,重发d3。

从这里可以发现快速重传机制有个问题:触发了d3的快速重传,但d4还没有重传,d4要等到自己的T4timeout到了或是三个ACK4才重传,显然时延加大了,有没有好的解决办法呢?这就引入了SACK。

SACK:SelectiveAcknowledgement选择性的应答。在TCK协议里的SACK就是接收放告知发送方收到了一些数据片段,它是ACK的补充,如上例,B通过ACK告知了A收到了d1,d2,但没告知A收到片段d5,d6,d7。

有了SACK,就可以提前触发d4的重传了。

3.QUIC的重传机制

与TCP的类似,同样用到ACK,SACK,RTO。但改进了TCP重传机制中的问题。

TCP重传机制的问题有3.1与3.2。

3.1重传歧义

由于重传的包的序号没有变更,导到ACK响应的不知是原始包还是重传包。

计算网络的来回时延rtt就可能出错,如下图所示:rtt=d3_t3-d3_t1,就错误的将rtt变大了。

SNACK带来的reneging问题,即接收方发了很多SNACK,且这些SNACK里携带了很多跳跃的应答数据,导致发送方大量的重传计算,这种往往是一种攻击手段。

3.2webrtc的重传机制

NACK:NegativeAcknowledgement消极应答。所谓消极应答,就是接收端不反馈收到哪些数据,而是反馈没有收到哪些数据。

当B收到d5后,通过对比序列号,发现d3,d4没收到,那么发送NACK,告知A,d3,d4丢失了,A就可以重传d3,d4了。

4.参考文献

ACK:https://tools.ietf.org/html/rfc793

SACK:https://tools.ietf.org/html/rfc2018

NACK:https://tools.ietf.org/html/rfc4585#page-20

RACK:https://www.ietf.org/id/draft-ietf-tcpm-rack-08.txt

Quic retransmition:https://tools.ietf.org/html/draft-ietf-quic-recovery-16