如何响应 Python 中使用套接字的 SSDP 搜索?
How to Respond to SSDP Searches with Sockets in Python?
我正在尝试创建一个类似于 Chromecast 的设备,它可以从 Internet 流式传输视频并进行远程控制。我使用 HTTP get 请求对设备进行远程控制,并使用以下代码侦听它们:
侦听对设备 (localhost) 的 HTTP 请求:
import socket
import sys
s = socket.socket()
host = "localhost"
port = 8060
s.bind(('', port))
s.listen(1)
try:
while True:
connection, clientAddress = s.accept()
try:
print clientAddress
//Do Command
//Reply
except:
print "Error"
except KeyboardInterrupt:
print('interrupt')
然后我开始实施 SSDP,以便其他设备可以找到我的设备并投射到它,并计划使用类似的代码来侦听 MSEARCH 请求,但 239.255.255.250:1900 除外。但是,当发送 MSEARCH 时,代码不会拾取它。
侦听“239.255.255.250:1900”上的 SSDP 搜索
import socket
import sys
s = socket.socket()
host = "239.255.255.250"
port = 1900
s.bind((host, port))
s.listen(10)
try:
while True:
connection, clientAddress = s.accept()
try:
print("Trigger")
print clientAddress
data = connection.recv(1048)
print data
except:
print "Error"
except KeyboardInterrupt:
print('interrupt')
问题:
所以问题是为什么两者的行为不同(我相信这是因为在第一个示例中,设备侦听也是 HTTP 请求的目的地,而在第二个示例中则不是) 以及修复代码以便我可以监听 SSDP 搜索的方法。
SSDP 是一个 UDP 协议,但您没有在套接字构造函数中指定 UDP。通过使用不带参数的套接字构造函数,
s = socket.socket()
您获得了默认参数:
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
如您所见,类型的默认值为 SOCK_STREAM
,即 TCP。相反,查看 this example 中的 server() 方法,其中一个片段是:
MCAST_GRP = '239.255.255.250'
MCAST_PORT = 1900
def server(timeout=5):
socket.setdefaulttimeout(timeout)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
sock.bind(('', MCAST_PORT))
mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
# ... more code at the link
我正在尝试创建一个类似于 Chromecast 的设备,它可以从 Internet 流式传输视频并进行远程控制。我使用 HTTP get 请求对设备进行远程控制,并使用以下代码侦听它们:
侦听对设备 (localhost) 的 HTTP 请求:
import socket
import sys
s = socket.socket()
host = "localhost"
port = 8060
s.bind(('', port))
s.listen(1)
try:
while True:
connection, clientAddress = s.accept()
try:
print clientAddress
//Do Command
//Reply
except:
print "Error"
except KeyboardInterrupt:
print('interrupt')
然后我开始实施 SSDP,以便其他设备可以找到我的设备并投射到它,并计划使用类似的代码来侦听 MSEARCH 请求,但 239.255.255.250:1900 除外。但是,当发送 MSEARCH 时,代码不会拾取它。
侦听“239.255.255.250:1900”上的 SSDP 搜索
import socket
import sys
s = socket.socket()
host = "239.255.255.250"
port = 1900
s.bind((host, port))
s.listen(10)
try:
while True:
connection, clientAddress = s.accept()
try:
print("Trigger")
print clientAddress
data = connection.recv(1048)
print data
except:
print "Error"
except KeyboardInterrupt:
print('interrupt')
问题:
所以问题是为什么两者的行为不同(我相信这是因为在第一个示例中,设备侦听也是 HTTP 请求的目的地,而在第二个示例中则不是) 以及修复代码以便我可以监听 SSDP 搜索的方法。
SSDP 是一个 UDP 协议,但您没有在套接字构造函数中指定 UDP。通过使用不带参数的套接字构造函数,
s = socket.socket()
您获得了默认参数:
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
如您所见,类型的默认值为 SOCK_STREAM
,即 TCP。相反,查看 this example 中的 server() 方法,其中一个片段是:
MCAST_GRP = '239.255.255.250'
MCAST_PORT = 1900
def server(timeout=5):
socket.setdefaulttimeout(timeout)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
sock.bind(('', MCAST_PORT))
mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
# ... more code at the link