Python 基于 UDP 交叉多路复用器

Python based UDP crossbar multiplexer

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

Crossbar Image

为此目的:

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

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

我已经在这上面花了几天时间了,真的很沮丧。我似乎无法想出一种以合理的方式存储 Source/Sink 连接的方法,而且我无法弄清楚如何让我的套接字 class 为每个源都有一个线程,就像我看到的所有示例一样用于使用单个端口创建多线程服务器。

我不是在找人帮我写这个,只是一些提示,我可以从那里弄清楚,因为对我来说完全理解代码比 copy/paste 更好。

谢谢

The goal is to have any data that is received on a Source replicated out to any Sinks attached to that Source.

这应该很简单。

I cant seem to figure out a way of storing the Source/Sink connections in a sensible way,

对于每个源,您需要存储一组零个或多个接收器,到达源的数据包将被转发到这些接收器。假设您将 Source 表示为某种 Python 对象,您可以给它一个 Python 字典(或者如果您更喜欢 Python 列表)和 add/remove 根据需要沉入 list/dictionary。然后,每当 Source 收到 UDP 数据包时,您只需遍历 list/dictionary 并在当前组中的每个 Sink 上调用 send()sendto()

I cant figure out how to get my socket class to have a thread for each Source as all the examples I see are for creating a multi-threaded server using a single port.

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

  • 将所有套接字设置为非阻塞模式
  • 在事件循环的顶部调用 select(),将所有源套接字的列表作为第一个参数,这样 select() 调用就不会 return 直到在其中一个套接字上接收到至少一个 UDP 数据包。
  • 当 select() returns 时,迭代它 returned 的准备好读取的 UDP 套接字列表,并从每个套接字中读取 UDP 数据包,转发它们如上所述,对于源套接字的关联接收器套接字来说是必要的。

请注意,为了获得最佳性能,您可能还需要监视套接字是否准备就绪,这样您就不会最终丢弃传出的 UDP 数据包 if/when 特定 UDP 套接字的传出数据缓冲区已满,但是对于初始实现,您可以通过假设您的 UDP 套接字传出数据缓冲区总是有足够的 space 用于您想要 send().[=17 的任何数据包来稍微作弊以简化事情=]