【问题标题】:listening for multicast traffic on mutiple networks侦听多个网络上的多播流量
【发布时间】:2012-12-21 12:25:26
【问题描述】:

我目前有以下接收多播数据的代码。

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', 24003))
mreq = struct.pack("=4sl", socket.inet_aton("238.210.10.1"), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

我有两个网卡,但代码只监听发送到 127.0.0.1 的消息。如何收听任何网卡上的所有多播消息?无需对它们进行硬编码。

【问题讨论】:

  • 尝试使用线程或 Twisted 框架?
  • Python select module 允许您在多个套接字上等待输入。我同意 Twisted 会很好,但我推荐 select 超过线程。
  • @RandomDownvoter 关心解释否决票?所以我可以尝试改进问题。
  • @ahenderson 它一定是问题正文中措辞正确的标题、准确的标记或完整的英文
  • @japreiss:当您不需要在连接之间共享任何数据时,线程会简单得多,但当您这样做时,线程会简单得多。因此,除非您需要处理数千个连接,否则这是最好的决定因素。 (如果您确实需要处理数千个连接,则不能使用线程……但此时,您可以考虑gevent,它实际上具有相同的简单性权衡。)

标签: python sockets networking multicast


【解决方案1】:
  1. UDP 套接字上没有“侦听”。这是一个 TCP 术语。您需要加入多播组通过所有适用的接口,循环它们。这样可以确保将 IGMP JOIN 消息发送到所有需要的网络,这样他们就会知道向您发送多播。

  2. 根据您的平台,您需要绑定到多播地址本身 (Linux) 或 INADDR_ANY = 0.0.0.0 (Windows)。我不确定 Unix 属于哪个阵营,但我怀疑在这种情况下它是 Windows 阵营。这样可以确保您可以通过任何接口接收数据报。

【讨论】:

    【解决方案2】:

    struct ip_mreq 允许您选择一个 接口来加入您想要的多播组。指定INADDR_ANY 让系统通过在路由表中查找匹配路由上的接口来为您执行此操作(这意味着任何 接口,而不是所有 接口)。如果您在 Unix 上,您可以使用 netstat -ng 查看为组成员选择了哪个接口。

    如果你想在 all 接口上加入同一个组,然后用if_nameindex(3) 枚举它们(你必须弄清楚如何在 Python 中做到这一点),为每个接口创建一个套接字, bind(2) 并使用接口索引或地址加入 (setsockopt(2)) 组,然后使用 select 轮询套接字。

    【讨论】:

    • 通过ctypes 访问if_nameindex API 时唯一棘手的一点是,有一个类型struct if_nameindex 和一个函数if_nameindex,你必须保持直截了当(就像stat )。否则,如果您曾经使用过 ctypes 并且知道如何使用 LoadLibrary('libc.so')(或 libc.dylib),那将是非常简单的事情。
    • 加入多播组不是“监听”。它在 UDP 中是一个被滥用的术语,它实际上根本没有任何意义。最好真的避免它。
    • 是的,我同意,“倾听”在这里不是正确的术语(我知道我可以指望你在我的答案中找到缺陷:),我会尝试重新措辞。
    猜你喜欢
    • 2011-11-09
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    • 2021-10-20
    • 2020-05-26
    相关资源
    最近更新 更多