简体   繁体   English

使用Twisted Python在特定接口上接收广播UDP

[英]Receiving broadcast UDP on a specific interface with Twisted Python

I am working on an Ubuntu 14.04 server with multiple interfaces on different subnets. 我正在开发一个Ubuntu 14.04服务器,在不同的子网上有多个接口。 I am trying to write a twisted(13.2.0) application that listens for broadcasts on one interface only, ignoring the other interfaces. 我正在尝试编写一个扭曲的(13.2.0)应用程序,它只在一个接口上侦听广播,忽略其他接口。

I am able to receive broadcasts with this code. 我可以使用此代码接收广播。

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import IN, socket, struct


class BroadcastListener(DatagramProtocol):

    def startProtocol(self):
        self.transport.getHandle().setsockopt(socket.SOL_SOCKET,
                                       socket.SO_BROADCAST, True)

    def datagramReceived(self, datagram, address):
        print "Received datagram from %s" % (address[0])

#reactor.listenUDP(65001, BroadcastListener(), interface='192.168.1.1')
reactor.listenUDP(3200, BroadcastListener())

reactor.run()

I am sending test UDP broadcasts from another machine on the 192.168.1.x subnet with socat. 我正在使用socat从192.168.1.x子网上的另一台机器发送测试UDP广播。

echo Hi |socat -  UDP-DATAGRAM:192.168.1.255:3200,broadcast

However, this will receive broadcasts on any interface on the server. 但是,这将在服务器上的任何接口上接收广播。 I thought it would be specificying the interface in reactor.listenUDP(), as I did the commented call. 我认为这将特定于reactor.listenUDP()中的接口,因为我做了评论调用。

If I use the reactor.listenUDP() call that includes the interface, I no longer receive broadcast. 如果我使用包含接口的reactor.listenUDP()调用,我将不再接收广播。 I still receive unicasted UDP sent with socat. 我仍然收到与socat一起发送的unicasted UDP。

echo Hi |socat -  UDP-DATAGRAM:192.168.1.1:3200

I can see when specifying the interface that the socket is bound to the interface. 我可以看到指定套接字绑定到接口的接口。

$ netstat -an |grep udp |grep 3200
udp        0      0 10.10.0.1:3200          0.0.0.0:*

But the broadcasts are being dropped. 但是广播被放弃了。 I confirmed with tcpdump the broadcasts are arriving to the server. 我用tcpdump确认广播到达服务器。

What is the correct way to set a UDP listener's interface in twisted python? 在twisted python中设置UDP侦听器接口的正确方法是什么?

I'm assuming you're on Linux here. 我假设你在Linux上。 It seems that bind() won't work because it drops packets not addressed to the interface, which for broadcast packets is all of them. 似乎bind()不起作用,因为它丢弃了没有寻址到接口的数据包,广播数据包就是这些数据包的全部。 Instead, try the socket option SO_BINDTODEVICE , which may not be in your Python socket module, but has the value 25 on my Linux system and probably on yours (check /usr/include/asm-generic/socket.h ). 相反,请尝试使用套接字选项SO_BINDTODEVICE ,它可能不在您的Python socket模块中,但在我的Linux系统上可能有25 ,而且可能在您的系统上(请检查/usr/include/asm-generic/socket.h )。 It takes an interface name rather than an IP address, so it should look something like this: 它需要一个接口名称而不是一个IP地址,所以看起来应该是这样的:

self.transport.getHandle().setsockopt(socket.SOL_SOCKET, 25, "eth0")

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

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