用 Python 编写一个可靠的、完全有序的多播系统

Dan*_*eck 5 python sockets ip networking multicast

我必须用 Python 从头开始​​编写一个可靠的、完全有序的多播系统。我不能使用任何外部库。我可以使用中央音序器。

似乎有两种直接的方法:

  1. 编写一个高效的系统,为每个多播消息附加一个唯一的 id,具有它接收到的消息 id 的定序器多播序列号,并来回发送 ACK 和 NACK。
  2. 编写一个低效的泛洪系统,其中每个多播器简单地重新发送它收到的每条消息一次(除非它是由该特定多播器发送的。)

我被允许使用第二个选项,并且我倾向于这样做。

我目前正在多播 UDP 消息(这似乎是唯一的选择),但这意味着某些消息可能会丢失。这意味着我必须能够唯一标识每个发送的 UDP 消息,以便可以根据 #2 重新发送。我真的应该生成唯一的数字(例如,使用发件人地址和计数器)并将它们打包到每个发送的 UDP 消息中吗?我该怎么做?以及如何在 Python 中接收单个 UDP 消息,而不是数据流(即socket.recv)?

Fra*_*rba 4

洪水方法可能会导致情况变得更糟。如果消息由于高网络负载而被丢弃,让每个节点重新发送每条消息只会使情况变得更糟。

采取的最佳方法取决于您发送的数据的性质。例如:

  1. 多媒体数据:无需重试,丢弃的数据包就是丢弃的帧,无论如何下一帧到达那里都无关紧要。
  2. 固定周期数据:接收节点保留一个计时器,每次收到更新时该计时器都会重置。如果时间到期,它会向主节点请求丢失的更新。重试可以单播到请求节点。

如果这两种情况都不适用(每个数据包都必须由每个节点接收,并且数据包时间是不可预测的,因此接收者无法自行检测丢失的数据包),那么您的选择包括:

  1. 来自每个节点对每个数据包的显式 ACK。发送方重试(单播)任何未确认的数据包。
  2. 基于 TCP 的网格方法,每个节点手动将收到的数据包重复发送到邻居节点,依靠 TCP 机制来确保传递。

您可能会依赖于接收者在收到序列号较晚的数据包时注意到丢失的数据包,但这要求发送者保留该数据包,直到至少发送了一个附加数据包。要求肯定的 ACK 更可靠(并且可证明)。