Windows下Python实现SSDP组播发现Yeelight设备失效问题排查
SSDP组播发现Yeelight设备Windows端失效问题
我正在开发一款通过SSDP组播发现Yeelight设备的应用,按照设备规范,需要向239.255.255.250的1982端口发送M-SEARCH消息。这段代码在两台MacOS设备上运行正常,但Windows端原本能用,隔了两天突然失效。我怀疑是Windows系统拦截了相关操作,但找不到问题根源。已经试过在防火墙添加例外、关闭杀毒软件,问题还是没解决。
相关Python代码
import socket import threading from pprint import pprint from time import sleep from colorama import Fore, Style discoveryAddress = ("239.255.255.250", 1982) discoveryMessage = "M-SEARCH * HTTP/1.1\r\n" + "HOST: 239.255.255.250:1982\r\n" + \ "MAN: \"ssdp:discover\"\r\n" + "ST: wifi_bulb\r\n" def doSearch(): ssdpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) ssdpSocket.sendto(str.encode(discoveryMessage), discoveryAddress) while True: response = ssdpSocket.recvfrom(1024) msg = format(response[0]) formattedResponse = formatResponse(msg.split('\\r\\n')) print("hi") print(Fore.GREEN, "Received response") print(Fore.WHITE, formattedResponse, '\n') def formatResponse(response: list) -> list: result = [] filteredAttr = ['HTTP', 'Location:', 'power:'] for s in response: for attr in filteredAttr: if attr in s: result.append(s) return result doSearch()
排查与修复建议
- 补全组播套接字必要配置:Windows对UDP组播的套接字配置要求更严格,原代码缺少组播成员加入和地址复用设置,添加以下代码:
ssdpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 加入组播组,允许接收组播响应 ssdpSocket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton("239.255.255.250") + socket.inet_aton("0.0.0.0")) # 设置超时,避免无限阻塞 ssdpSocket.settimeout(10) - 修正M-SEARCH消息格式:SSDP要求消息末尾必须有一个空行(额外的
\r\n),否则设备可能不识别。修改消息定义:discoveryMessage = "M-SEARCH * HTTP/1.1\r\n" + "HOST: 239.255.255.250:1982\r\n" + \ "MAN: \"ssdp:discover\"\r\n" + "ST: wifi_bulb\r\n\r\n" - 修复响应解析逻辑:原代码用
format(response[0])处理字节数据会引入多余的b'和转义符,导致分割错误,改为直接解码:msg = response[0].decode('utf-8') formattedResponse = formatResponse(msg.split('\r\n')) - 检查网络适配器绑定:如果Windows切换了网络(如从有线到无线),可以指定套接字绑定到当前活跃网卡的本地IP,避免组播包发送到错误适配器:
ssdpSocket.bind(("192.168.1.100", 0)) # 替换为你的实际本地IP - 抓包验证流量:用Wireshark抓
udp port 1982的包,确认M-SEARCH消息是否发出,以及Yeelight设备是否返回响应。如果没收到响应,排查设备是否在同一网段、是否开启了SSDP发现;如果收到响应但代码没捕获,检查套接字配置。
内容的提问来源于stack exchange,提问作者Daanooo
相关产品推荐
相关产品推荐

