[英]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.