在谷歌搜索高低之后我还没有找到以下问题的明确答案: 大致遵循以下指南: http://twistedmatrix.com/documents/10.2.0/core/howto/udp.html#auto3
如何将扭曲的多播侦听器绑定到 ONLY 多播地址以及特定或所有接口上。
在查看reactor.listenMulticast时,它不为硬件接口提供抽象,只提供由IP地址表示的伪接口。我找不到一种只在多播地址上绑定的方法,例如224.0.0.1的特定接口或所有接口。 任何人都可以提供更多相关信息吗?
答案 0 :(得分:3)
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
调用直接公开它会很好,但假设这有效,那将是一个非常简单的补丁。如果这可以解决您的问题,请告诉我。
答案 1 :(得分:3)
其他答案可能会解决问题,但在多个界面上监听多播组的方式有“更加扭曲”(可能更容易)。
在一个或多个界面上侦听多播组
要在一个或多个接口上侦听多播组,请在协议的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地址。
答案 2 :(得分:1)
一个简单的,如果重手的方法可以通过类似的方式指定路线:
sudo route add 239.255.0.0 -interface en0 -netmask 255.255.0.0