【问题标题】:Receiving broadcast UDP on a specific interface with Twisted Python使用 Twisted Python 在特定接口上接收广播 UDP
【发布时间】:2015-04-03 11:18:37
【问题描述】:

我正在开发一个 Ubuntu 14.04 服务器,在不同的子网上有多个接口。我正在尝试编写一个 twisted(13.2.0) 应用程序,它只在一个接口上侦听广播,而忽略其他接口。

我可以使用此代码接收广播。

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()

我正在使用 socat 从 192.168.1.x 子网上的另一台机器发送测试 UDP 广播。

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

但是,这将在服务器上的任何接口上接收广播。我认为它会在 reactor.listenUDP() 中指定接口,就像我在注释调用中所做的那样。

如果我使用包含接口的 reactor.listenUDP() 调用,我将不再接收广播。我仍然收到使用 socat 发送的单播 UDP。

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

指定接口的时候可以看到socket绑定的接口。

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

但是广播正在被丢弃。我通过 tcpdump 确认广播正在到达服务器。

在 twisted python 中设置 UDP 侦听器接口的正确方法是什么?

【问题讨论】:

  • 你试过self.transport.getHandle().bind('192.168.1.1')吗?
  • 我在 setsockopt() 行的上方和下方都有 self.transport.getHandle().bind(('192.168.1.1', 3200))。我应该把它放在别的地方吗?

标签: python python-2.7 twisted twisted.internet


【解决方案1】:

我假设您在这里使用的是 Linux。似乎bind() 不起作用,因为它丢弃了未发送到接口的数据包,对于广播数据包来说,这些数据包就是所有这些。相反,请尝试使用套接字选项SO_BINDTODEVICE,它可能不在您的 Python socket 模块中,但在我的 Linux 系统和您的 Linux 系统上具有值 25(检查 /usr/include/asm-generic/socket.h)。它需要一个接口名称而不是 IP 地址,所以它应该看起来像这样:

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

【讨论】:

  • 这似乎是对 Twisted 的一个潜在有用的补充,如果这实际上是唯一的方法。我承认我自己实际上并不知道如何做到这一点:)。
  • 我现在看到它是 linux。我知道绑定到设备会起作用,但读取该选项仅限于 linux。我也在考虑使用 IP_PKTINFO 来获取数据报发送到的地址,但我认为这也不支持多平台。我最终可能会检索接口配置并将发送者与网络掩码进行比较。
猜你喜欢
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-05
相关资源
最近更新 更多