我正在编写一个 Boost 版本的BitTorrent uTorrent 传输协议(一种基于 UDP 数据报的缓冲区敏感可靠流协议)。我的目标是拥有一个 UDP 套接字管理器,它可以发送和接收数据报,并管理许多 uTP 连接的所有拥塞和错误控制。客户端线程可以通过说创建新的 uTP 连接,utp_manager.async_connect( endpoint )
或者通过说接受入站连接utp_manager.async_accept( handler )
uTP 规范有点单薄,我看不到在以下情况下如何处理 ACK 号:
DATA (seq=1) ----------------> received OK
X-------- ACK=1 (not received)
DATA (seq=2) ----------------> received OK
<---------------- ACK=2 (received OK)
发送方是否将 DATA-1 视为 ACK,因为它收到了 ACK=2?还是会重新发送DATA-1?在这种情况下,接收者是否会发送 ACK=1,即使它已经确认了 2?
我认为规则需要是:
- 接收方总是为它收到的最高连续SEQ_NR 发送 ACK(不是它收到的最后一个数据包的 SEQ_NR,如规范所述)
- 发送方可以假设所有数据包都已收到(加上任何选择性 ACK 数据包),即使没有收到一个 ACK(如我上面的示例)
- 如果接收器有任何间隙,它将继续 ACKing 在第一个丢失数据包之前收到的最后一个数据包的 SEQ_NR(加上它所做的任何选择性 ACK)。
- 当发送方接收到 3 个重复的 ACK 或 ACK_NR 之后的 3 个数据包已通过选择性 ACK 确认时,发送方在 ACK_NR + 1 处重新传输数据包。
我知道我可以尝试设置这些场景并针对现有实现运行它们,但我认为没有任何参考实现可以保证是正确的,而且设置起来很乏味。我希望研究或实施该协议的人能够说出我是否做对了,或者我错过了什么。