python - 无法在 python 中读取来自 udp 多播的响应
问题描述
在发送多播后,我似乎无法读取发回给我的响应。tcpdump 显示原始多播和响应都已发送。有人可以建议以下python程序有什么问题吗?我的目标是广播发现然后读取响应(正如您从下面的 tcpdump 中看到的那样)不是作为多播发送回的,而是点对点发送回发送端口。
#!/usr/bin/env python
from socket import socket, AF_INET, SOCK_DGRAM, IPPROTO_UDP
from textwrap import dedent
from soco.utils import really_utf8
PLAYER_SEARCH = dedent("""\
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 1
ST: urn:schemas-upnp-org:device:ZonePlayer:1
""").encode('utf-8')
MCAST_GRP = '239.255.255.250'
MCAST_PORT = 1900
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
sock.sendto(really_utf8(PLAYER_SEARCH), (MCAST_GRP, MCAST_PORT))
print(sock)
data, addr = sock.recvfrom(1024, 0) # hangs here forever
if data:
print("Found Broadcast server at : ", addr)
print(data)
控制台输出如下:
$ python simplesock.py
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=17, laddr=('0.0.0.0', 40690)>
打印sock
等待输入后程序挂起。
这是我运行上述程序时得到的 tcpdump。请注意,服务器正在响应控制台输出中上面列出的端口,因此服务器肯定收到了我的原始消息。
21:27:36.864212 IP (tos 0x0, ttl 1, id 41099, offset 0, flags [DF], proto UDP (17), length 147)
ThinkPad-T480s.fios-router.home.40690 > 239.255.255.250.1900: UDP, length 119
E.....@...&m...........l....M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 1
ST: urn:schemas-upnp-org:device:ZonePlayer:1
21:27:37.361046 IP (tos 0x0, ttl 64, id 25095, offset 0, flags [DF], proto UDP (17), length 524)
SonosZP.fios-router.home.34982 > ThinkPad-T480s.fios-router.home.40690: UDP, length 496
E...b.@.@.R...............Z.HTTP/1.1 200 OK
CACHE-CONTROL: max-age = 1800
EXT:
LOCATION: http://192.168.1.195:1400/xml/device_description.xml
SERVER: Linux UPnP/1.0 Sonos/50.1-65071 (ZPS12)
ST: urn:schemas-upnp-org:device:ZonePlayer:1
USN: uuid:RINCON_347E5CC2374C01400::urn:schemas-upnp-org:device:ZonePlayer:1
X-RINCON-HOUSEHOLD: Sonos_xxxUTzAZjabcDsaBadOOK2GQFP
X-RINCON-BOOTSEQ: 2
X-RINCON-WIFIMODE: 1
X-RINCON-VARIANT: 2
HOUSEHOLD.SMARTSPEAKER.AUDIO: Sonos_xxxUTzAZjabcDsaBadOOK2GQFP.RmcmkwBQ12BxWPa_fNdS
在 Ubuntu 18.04.2 LTS 上运行的 Python 3.6.7
解决方案
您没有加入多播组:
sock.setsockopt(
socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(multicast_address) + socket.inet_aton(bind_address)
)
这是异步的listen_ssdp
方法:https ://github.com/lbryio/aioupnp/blob/v0.0.14/aioupnp/protocols/ssdp.py#L121
它使用成功接收对 SSDP/m-search 请求的SSDPProtocol
回复,就像您发送的一样。
还要记住,路由器对它们将回复的 m-search 数据包的格式非常挑剔,其中一些以非常愚蠢的方式偏离了所谓的规范。如果您始终没有从代码中获得回复,而是从 torrent 客户端或 之类的东西中获得回复,请miniupnpc
尝试捕获成功的库发送的内容,以便您可以复制它。
推荐阅读
- swiftui - 在 iOS WidgetKit 小部件中右对齐 Text(Date(), style: .timer) 文本
- android - 如何从 APK 转储文件?
- python - 如何在列表中添加所有相同的浮点值,然后将这些值放在新列表中
- android - Android Java FCM 不生成令牌
- python - 使用带有参数化测试的 factoryboy
- c++ - 标准::地图
插入结果错误? - javascript - 函数只在for循环中执行一次
- java - 社交网络应用程序:个人资料照片显示不正确
- python - 二叉树中特定节点的总和
- pygame - pygame没有安装在jetson nano上