实现UDP多播可靠的方法



我正在为我的大学考试做准备,去年的一个问题是"如何使UDP多播可靠"(如tcp,重传丢失的数据包(

我想到了这样的东西:

  1. 服务器使用UDP 发送多播

  2. 每个客户端发送接收到该数据包的确认(使用TCP(

  3. 若服务器意识到并不是每个人都接收到数据包,它会向特定的客户端重新发送多播或单播

问题是,可能有一个客户端通常丢失了数据包,并迫使服务器重新发送。

它好吗?

每个客户端发送接收到该数据包的确认(使用TCP(

为每个数据包发送ACK,并使用TCP进行发送,对于大量接收器来说是不可扩展的。使用基于NACK的方案更有效。

从服务器发送的每个数据包都应该有一个与之相关的序列号。当客户端接收到这些数据包时,他们会跟踪遗漏了哪些序列号。如果数据包丢失,则可以通过UDP将NACK消息发送回服务器。该NACK可以被格式化为序列号的列表或者接收/未接收序列号的位图。

若服务器意识到并不是每个人都接收到数据包,它会向特定的客户端重新发送多播或单播

当服务器接收到NACK时,它不应该立即重新发送丢失的数据包,而是等待一段时间,通常是GRTT(组往返时间——接收器组中最大的往返时间(的倍数。这给了它时间来累积来自其他接收器的NACK。然后服务器可以多播丢失的数据包,这样任何丢失数据包的客户端都可以接收到它们。

如果此方案用于文件传输,而不是流式传输数据,则服务器可以交替发送文件数据。完整的文件在第一次通过时发送,在此期间,累积接收到的任何NACK,并标记需要重新发送的数据包。然后,在随后的传递中,只发送重传。这具有的优点是,具有较低丢失率的客户端将有机会完成接收文件,而高丢失接收器可以继续接收重传。

问题是,可能有一个客户端通常丢失了数据包,并迫使服务器重新发送。

对于损失非常大的客户端,服务器可以设置丢失数据包的最大百分比的阈值。如果客户端发送的NACK超过该阈值一次或多次(次数由服务器决定(,则服务器可以丢弃该客户端,并且不接受其NACK,或者向该客户端发送消息,通知其已丢弃。


有许多协议可以实现这些功能:

  • UFTP-基于UDP的加密FTP与多播(披露:作者(
  • 面向NACK的可靠多播
  • PGM-实用的通用多播
  • UDPCast

相关RFC:

  • RFC 4654-TCP友好多播拥塞控制(TFMCC(:协议规范
  • RFC 5401-多播否定确认(NACK(构建块
  • RFC 5740-面向NACK的可靠多播(NORM(传输协议
  • RFC 3208-PGM可靠传输协议规范

要使UDP可靠,您必须处理一些事情(即,自己实现它(。

连接处理:发送和接收进程之间的连接可能会断开。大多数可靠的实现通常发送keep-Alive消息来维护两端之间的连接。

排序:消息在发送之前需要拆分成块。

确认:收到每条消息后,需要向发送进程发送一条ACK消息。这些ACK消息也可以通过UDP发送,而不必通过UDP。接收过程可能会意识到这已经丢失了一条信息。在这种情况下,它将停止从保留队列(保存接收到的消息的消息队列,就像消息的等候室(传递消息,并请求重新发送丢失的消息。

流量控制:根据接收过程传递数据的能力来限制数据的发送。

通常,一组流程都有一个领导者。这些组中的每一个通常都有一个领导者和整个组的视图。这被称为虚拟同步。

最新更新