可靠的UDP和ACK方法问题

7

我正在研究可靠UDP的实现(即发送ACK数据包并重新发送未收到ACK的数据包)。

在网上找到的两种主要模式如下:

  1. 客户端为每个接收到的数据包发送一个带有该数据包序列号的ACK。服务器假定除非收到ACK,否则数据包未被传送。

  2. 客户端发送一个带有它认为丢失的数据包序列号的ACK数据包。服务器假定数据包已传递,除非从客户端收到一个说它缺少一个序列号的ACK,然后重新发送请求的(缺失的)数据包。

简而言之,在1中,客户端发送接收到的数据包序列号,而在2中,客户端发送缺失的数据包序列号。

想知道每种方法的优缺点是什么,哪一种更为主流(我认为是1,但2似乎是一种非常聪明的方法,因为大多数数据包都到达了,只有很少的数据包通常会丢失)。

编辑: 以下是这两种方法的简短示例:

Method 1: Server sends: 1,2,3,4,5 
Client received: 1,3,5,4 
Client sends back: ACK 1, ACK 3, ACK 5, ACK 4  
Server resends: 2.. maybe more if ACK packets were lost


Method 2:
Server sends 1,2,3,4,5,6,7,8
Client receives: 1,3,2,5,7
Client Sends :ACK (lowest continuous 3,highest received 7,  seem to be missing 4,6)
Server resends: 4,6,8

如果在第二种方法中,客户端表示缺少某些内容的确认数据包从未被传递,那又怎样呢? - villintehaspam
据我所知,在第二种方法中,ACK会说“这里没有丢失的数据包(最高接收序列为532)”...因此,如果服务器发送了1个数据包并且没有收到ACK,则该数据包将被重新发送。此外,第二种方法中的ACK数据包通常会定期发送...就像ping一样。 - Radu094
那么,您可以再详细解释一下这两种方法的区别吗?因此,方法1在每次到达新的序列号时显式地确认数据包(因此可能是多个数据包的确认),而方法2则定期隐式地确认数据包,从不显示显式确认。 - villintehaspam
1
不,方法1会为每个接收到的数据包发送一个ACK,没有嵌入其他逻辑。方法2定期发送ACK,并嵌入一些逻辑来提供某种传输窗口:我已经收到了序列号为40之前的所有数据包,但好像缺少41、45和47号数据包。(或者:我已经收到了序列号为56的所有数据包,没有丢失任何数据包) - Radu094
1个回答

8

#2也被称为负确认(Negative ACK),又被称为NAK,它是传输方式的一种乐观视角。这意味着当传输正常工作时,它可以更好地扩展。

#1则是一种悲观的视角,假设传输将经常失败。

TCP使用ACKs是因为拥塞控制对于丢弃数据包以执行通信流形成公平网络具有基本依赖性。可靠UDP通道通常使用NAK,因为您正在使用可靠的高速媒介或低速流,需要低延迟,而不是基本ACK实现的锁步传输。

请注意,如果您提升到更高的层面,并查看可靠UDP通道上方的订阅管理,那么ACK或NAK的使用就没有明显的优势。在高速高容量网络上,市场数据世界已经证明了两种技术的使用。对于订阅,ACK具有优点,即在网络故障后不需要复杂的重新同步,但是每个主机发出重新订阅时,您将看到网络和CPU使用率的持续峰值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接