繁体   English   中英

Python扭曲的框架多播绑定在特定的接口上

[英]Python twisted framework multicast bind on specific interface

在google上搜索高低之后我还没有找到以下问题的明确答案:大致遵循以下指南: http//twistedmatrix.com/documents/10.2.0/core/howto/udp.html#auto3

如何将双绞线多播侦听器绑定到多播地址以及特定或所有接口上。

在查看reactor.listenMulticast时,它不为硬件接口提供抽象,只提供由IP地址表示的伪接口。 我找不到只绑定多播地址的方法,例如特定接口或所有接口的224.0.0.1。 任何人都可以提供更多相关信息吗?

其他答案可以解决问题,但是在多个接口上监听多播组的方式有“更加扭曲”(并且可能更容易)。

在一个或多个接口上侦听多播组

要在一个或多个接口上侦听多播组,请在协议的transport.joinGroup()方法的多次调用中提供每个所需接口的IP作为“接口”参数。

下面是一个适用于我的Linux机器的示例,它将使您的系统在特定接口上侦听多播。 将IP地址替换为属于您系统的IP地址。

#!/usr/bin/env python

from twisted.internet import protocol
from twisted.internet import reactor

class MyProtocol(protocol.DatagramProtocol):
    def startProtocol(self):
        # Join a multicast group, 224.0.0.9, on the interface belonging
        # to each of these IPs.
        # XXX Replace the interface_ips with one or more IP addresses belonging
        # to your system.
        for interface_ip in ["192.168.2.2", "10.99.1.100"]:
            self.transport.joinGroup("224.0.0.9", interface_ip)

if __name__ == "__main__":
    reactor.listenMulticast(1520, MyProtocol())
    reactor.run()

您可以使用/sbin/ip maddr show命令检查接口是否正在侦听新的多播组。 在命令输出中找到所需的接口名称,并验证多播组是否显示在其下方。

原始帖子中链接的UDP服务器示例应该能够通过更改对joinGroup()的调用来包含第二个IP地址参数来执行相同的操作,如上所述。

从特定IP发送多播

如果您正在接收套接字上的组播数据,那么您可能也希望发送多播数据 - 可能是多个接口。 由于它密切相关,并且我将把它放在这里的例子很少。 在twisted.internet.protocol.DatagramProtocol对象中,您可以使用self.transport.setOutgoingInterface()方法来控制将用于后续调用self.transport.write()的源IP。 显示从多个IP /接口发送消息的示例:

class MyProtocol(protocol.DatagramProtocol):
    # ...
    def send_stuff(self, msg):
        for src_ip in ["10.0.0.1", "192.168.1.1"]:
            self.transport.setOutgoingInterface(src_ip)
            self.transport.write(msg, ("224.0.0.9", 1520))

假设这些IP分配给两个不同的接口。 使用Wireshark嗅探您会看到从第一个接口发出的消息,然后是第二个接口,使用每个IP作为相应传输的源IP地址。

reactor.listenMulticast返回twisted.internet.udp.MulticastPort对象。 该对象拥有您正在侦听的套接字。 因此,请继续查看reactor.listenMulticast的结果,并设置相应的套接字选项(在本例中,它看起来像SO.BINDTODEVICE)以及一个以null结尾的设备字符串。

import IN, socket, struct

udp_port = reactor.listenMulticast(8005, MulticastServerUDP())
dev = "eth0" + "\0"
udp_port.socket.setsockopt(socket.SOL_SOCKET, IN.SO_BINDTODEVICE, dev)
reactor.run()

如果直接通过listenMulticast调用公开它会很好,但假设这有效,那将是一个非常简单的补丁。 如果这可以解决您的问题,请告诉我。

一个简单的,如果重手的方法可以通过以下方式指定路线:

sudo route add 239.255.0.0 -interface en0 -netmask 255.255.0.0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM