我正在准备我的大学考试,去年的一个问题是“如何使 UDP 多播可靠”(如 tcp,丢失数据包的重传)
我想过这样的事情:
服务器使用 UDP 发送多播
每个客户端都发送接收该数据包的确认(使用 TCP)
如果服务器意识到不是每个人都收到数据包,它会重新发送多播或单播到特定的客户端。
问题是可能有一个客户端通常会丢失数据包并强制服务器重新发送。
好吗 ?
我正在准备我的大学考试,去年的一个问题是“如何使 UDP 多播可靠”(如 tcp,丢失数据包的重传)
我想过这样的事情:
服务器使用 UDP 发送多播
每个客户端都发送接收该数据包的确认(使用 TCP)
如果服务器意识到不是每个人都收到数据包,它会重新发送多播或单播到特定的客户端。
问题是可能有一个客户端通常会丢失数据包并强制服务器重新发送。
好吗 ?
每个客户端都发送接收该数据包的确认(使用 TCP)
为每个数据包发送一个 ACK 并使用 TCP 来执行此操作,对于大量接收者是不可扩展的。使用基于 NACK 的方案更有效。
从服务器发送的每个数据包都应该有一个与之关联的序列号。当客户收到它们时,他们会跟踪丢失了哪些序列号。如果数据包丢失,则可以通过 UDP 将 NACK 消息发送回服务器。此 NACK 可以格式化为序列号列表或接收/未接收序列号的位图。
如果服务器意识到不是每个人都收到数据包,它会重新发送多播或单播到特定的客户端。
当服务器收到 NACK 时,它不应该立即重新发送丢失的数据包,而是等待一段时间,通常是 GRTT(组往返时间 - 接收器集中最大的往返时间)的倍数。这使它有时间从其他接收器累积 NACK。然后服务器可以多播丢失的数据包,以便任何丢失它们的客户端都可以接收它们。
如果此方案用于文件传输而不是流数据,则服务器可以交替发送文件数据。第一次发送完整的文件,在此期间累积接收到的任何 NACK,并标记需要重新发送的数据包。然后在随后的传递中,仅发送重传。这样做的好处是具有较低丢失率的客户端将有机会完成接收文件,而高丢失率的接收者可以继续接收重传。
问题是可能有一个客户端通常会丢失数据包并强制服务器重新发送。
对于丢失率非常高的客户端,服务器可以设置丢失数据包的最大百分比的阈值。如果客户端发送回超过该阈值的 NACK 一次或多次(多少次取决于服务器),服务器可以丢弃该客户端并且不接受其 NACK 或向该客户端发送消息,通知它它是掉了。
有许多协议可以实现这些功能:
相关的 RFC:
为了使 UDP 可靠,您必须处理一些事情(即,自己实现它)。
连接处理:发送和接收进程之间的连接可以断开。大多数可靠的实现通常会发送 keep-Alive 消息以维持两端之间的连接。
排序:消息在发送前需要拆分成块。
确认:在收到每条消息后,需要向发送进程发送一个 ACK 消息。这些 ACK 消息也可以通过 UDP 发送,不一定要通过 UDP。接收进程可能会意识到已经丢失了一条消息。在这种情况下,它将停止从保留队列(保存接收到的消息的消息队列,它就像一个消息的等待室)中传递消息,并请求重新传输丢失的消息。
流量控制:根据接收进程传递数据的能力来限制数据的发送。
通常,有一组进程的领导者。这些组中的每一个通常都有一个领导者和整个组的视图。这称为虚拟同步。