簡體   English   中英

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

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

我正在開發一個Ubuntu 14.04服務器,在不同的子網上有多個接口。 我正在嘗試編寫一個扭曲的(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一起發送的unicasted UDP。

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

我可以看到指定套接字綁定到接口的接口。

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

但是廣播被放棄了。 我用tcpdump確認廣播到達服務器。

在twisted python中設置UDP偵聽器接口的正確方法是什么?

我假設你在Linux上。 似乎bind()不起作用,因為它丟棄了沒有尋址到接口的數據包,廣播數據包就是這些數據包的全部。 相反,請嘗試使用套接字選項SO_BINDTODEVICE ,它可能不在您的Python socket模塊中,但在我的Linux系統上可能有25 ,而且可能在您的系統上(請檢查/usr/include/asm-generic/socket.h )。 它需要一個接口名稱而不是一個IP地址,所以看起來應該是這樣的:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM