如何响应 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