基于Python的UDP交叉开关多路复用器

问题描述

我在 python 中创建 UDP crossbar 多路复用器时遇到问题。我需要的是创建一个程序,其中有许多 UDP 数据的源和接收器。

Crossbar Image

为此目的:

  • 源是在指定端口上接受数据的 UDP 套接字。
  • 每个源使用不同的端口号。
  • Sink 是将数据发送到指定端口的 UDP 套接字。
  • 每个 Sink 使用不同的端口 号码

在上图中,您可以看到 Sink 1 连接到 Source 3,Sink 2 连接到 Source 1,等等。注意 Source 1 也连接到 Sink n。

目标是将 Source 上接收到的任何数据复制到连接到该 Source 的任何 Sink。我需要能够即时更改源/接收器连接。当没有接收器连接到源端口时,源端口接收到的任何数据都会被分箱/忽略(不排队)。

我现在已经花了几天时间,并且非常沮丧。我似乎无法找到一种以合理的方式存储 Source/Sink 连接的方法,而且我无法弄清楚如何让我的套接字类为每个 Source 拥有一个线程,因为我看到的所有示例都用于创建一个多线程使用单个端口的线程服务器。

我不是在找人为我写这个,只是一些提示,我可以从那里弄清楚,因为对我来说完全理解代码而不是复制/粘贴会更好。

谢谢

解决方法

目标是复制 Source 上收到的任何数据 输出到连接到该源的任何接收器。

那应该足够简单了。

我似乎想不出一种存储源/接收器连接的方法 以一种明智的方式,

对于每个源,您需要存储到达源的数据包将转发到的零个或多个接收器的集合。假设您将 Source 表示为某种 Python 对象,您可以给它一个属性,即 Python 字典(或者,如果您更喜欢 Python 列表),并根据需要向该列表/字典添加/删除接收器。然后,每当 Source 收到 UDP 数据包时,您只需遍历列表/字典并在当前组中的每个 Sink 上调用 send()sendto()

我不知道如何让我的套接字类为每个类都有一个线程 来源,因为我看到的所有示例都是用于创建多线程 服务器使用单个端口。

我建议避免使用多线程,因为对于这个用例来说它不是必需的,并且会引入很多最好避免的复杂情况。相反:

  • 将所有套接字设置为非阻塞模式
  • 在事件循环的顶部调用 select(),将所有源套接字的列表作为第一个参数,以便 select() 调用在至少有一个 UDP 数据包之前不会返回已在其中一个套接字上收到。
  • 当 select() 返回时,遍历它返回的可供读取的 UDP 套接字列表,并从每个套接字读取 UDP 数据包,根据需要将它们转发到源套接字的关联接收器套接字,如上所述。

请注意,为了获得最佳性能,您可能还需要监视套接字以准备好写入,以便在特定 UDP 套接字的传出数据缓冲区已满时不会丢弃传出的 UDP 数据包,但对于初始您可以通过假设您的 UDP 套接字传出数据缓冲区始终有足够的空间来容纳您想要 send() 的任何数据包,从而稍微作弊以简化事情。