在Python中编写一个可靠的,完全有序的多播系统

时间:2008-10-06 21:03:56

标签: python sockets networking ip multicast

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

似乎有两种直接方法:

  1. 编写一个有效的系统,为每个多播消息附加一个唯一的id, 具有它接收的消息id的定序器多播序列号, 并来回发送ACK和NACK。
  2. 编写一个效率低下的洪水系统,每个多播器只需重新​​发送一个 它收到的消息一次(除非它是由那个特定的多人发送的。)
  3. 我被允许使用第二种选择,我倾向于这样做。

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

3 个答案:

答案 0 :(得分:4)

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

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

  1. 多媒体数据:没有重试,丢弃的数据包是丢弃的帧,无论如何,当下一帧到达那里时无关紧要。
  2. 固定期间数据:收件人节点保留每次收到更新时重置的计时器。如果时间到期,它会从主节点请求丢失的更新。重试可以是请求节点的单播。
  3. 如果这些情况都不适用(每个节点都必须接收每个数据包,并且数据包时间不可预测,因此收件人无法自行检测丢失的数据包),那么您的选项包括:

    1. 每个节点对每个数据包的显式确认。发件人重试(单播)任何未确认的数据包。
    2. 基于TCP的网格方法,其中每个节点都手动重复接收的数据包到邻居节点,依靠TCP机制来确保传递。
    3. 您可能依赖收件人在接收到具有较晚序列号的数据包时注意到丢失的数据包,但这需要发送者保留数据包,直到至少发送了一个附加数据包。要求肯定的ACK更可靠(且可证明)。

答案 1 :(得分:1)

您采取的方法将在很大程度上取决于您发送的数据的性质,网络的规模以及您发送的数据量。特别是它将取决于每个节点连接的目标数量。

如果您希望将此扩展到每个节点的大量目标和大量数据,那么您可能会发现向每个数据包添加ACK / NAK的开销足以对吞吐量产生负面影响,特别是当您将重新添加到混音中时。

正如Frank Szczerba所说,多媒体数据的好处是可以从丢失的数据包中恢复。如果您对要发送的数据有任何控制权,则应尝试设计有效负载,以便最大限度地减少丢弃数据包的可能性。

如果您发送的数据无法容忍丢弃的数据包,那么您尝试扩展到网络的高利用率,那么udp可能不是最好的协议。实现一系列tcp代理(每个节点重新传输,单播,到所有其他连接的节点 - 类似于您的洪水想法)将是一种更可靠的机制。

综上所述,您是否考虑过为此应用程序使用真正的多播?


刚看到“家庭作业”标签......这些建议可能不适合家庭作业问题。

答案 2 :(得分:0)

恕我直言,您应该选择现有的可靠 UDP 协议。您可以选择几个,看看这个 SO 问题:What do you use when you need reliable UDP?

我个人喜欢并使用 MoldUDP,这是纳斯达克的 ITCH 市场数据馈送使用的协议。