首页 > 解决方案 > 基于 Python 的 UDP 交叉开关多路复用器

问题描述

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

横杆图像

为此目的:

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

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

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

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

谢谢

标签: pythonmultithreadingsocketsudpmultiplexing

解决方案


目标是将在 Source 上接收到的任何数据复制到附加到该 Source 的任何 Sink 上。

这应该足够直截了当。

我似乎无法找到一种以合理的方式存储 Source/Sink 连接的方法,

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

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

我建议避免使用多线程,因为这个用例没有必要,并且引入了很多最好避免的并发症。反而:

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

请注意,为了获得最佳性能,您可能还需要监视套接字的写入就绪状态,以便在特定 UDP 套接字的传出数据缓冲区已满时不会丢弃传出的 UDP 数据包,但对于初始实现,您可以通过假设您的 UDP 套接字输出数据缓冲区将始终为您想要的任何数据包提供足够的空间来简化事情send()


推荐阅读