前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SSDP协议的Python示例「建议收藏」

SSDP协议的Python示例「建议收藏」

作者头像
全栈程序员站长
发布2022-11-10 15:49:57
7300
发布2022-11-10 15:49:57
举报
文章被收录于专栏:全栈程序员必看

废话少说,直接上代码。服务端ssdp_server.py:

代码语言:javascript
复制
# -*- coding: utf-8 -*-
import socket
SSDP_ADDR = '239.255.255.250'
SSDP_PORT = 1900
SERVICE_NAME = 'my_service'
class Connection():
def __init__(self, s, data, addr):
self.__s = s
self.__data = data
self.__addr = addr
self.is_find_service = False
def handle_request(self):
if self.__data.startswith('M-SEARCH * HTTP/1.1\r\n'):
self.__handle_search()
elif self.__data.startswith('HTTP/1.1 200 OK\r\n'):
self.__handle_ok()
def __handle_search(self):
props = self.__parse_props(['HOST', 'MAN', 'ST', 'MX'])
if not props:
return
if props['HOST'] != '%s:%d' % (SSDP_ADDR, SSDP_PORT) \
or props['MAN'] != '"ssdp:discover"' \
or props['ST'] != 'ssdp:all':
return
print 'RECV: %s' % str(self.__data)
print 'ADDR: %s' % str(self.__addr)
response = 'HTTP/1.1 200 OK\r\nST: %s\r\n\r\n' % SERVICE_NAME
self.__s.sendto(response, self.__addr)
def __handle_ok(self):
props = self.__parse_props(['ST'])
if not props:
return
if props['ST'] != SERVICE_NAME:
return
print 'RECV: %s' % str(self.__data)
print 'ADDR: %s' % str(self.__addr)
print 'Find service!!!!'
self.is_find_service = True
def __parse_props(self, target_keys):
lines = self.__data.split('\r\n')
props = {}
for i in range(1, len(lines)):
if not lines[i]:
continue
index = lines[i].find(':')
if index == -1:
return None
props[lines[i][:index]] = lines[i][index + 1:].strip()
if not set(target_keys).issubset(set(props.keys())):
return None
return props
class SSDPServer():
def __init__(self):
self.__s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.__s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
local_ip = socket.gethostbyname(socket.gethostname())
any_ip = '0.0.0.0'
# 绑定到任意地址和SSDP组播端口上
self.__s.bind((any_ip, SSDP_PORT))
# INFO: 使用默认值
# self.__s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 20)
# self.__s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
# self.__s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF,
#                     socket.inet_aton(intf) + socket.inet_aton('0.0.0.0'))
# INFO: 添加到多播组
self.__s.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(SSDP_ADDR) + socket.inet_aton(local_ip))
self.local_ip = local_ip
def start(self):
while True:
data, addr = self.__s.recvfrom(2048)
conn = Connection(self.__s, data, addr)
conn.handle_request()
self.__s.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP,
socket.inet_aton(SSDP_ADDR) + socket.inet_aton(self.local_ip))
self.__s.close()
if __name__ == '__main__':
port = SSDPServer()
port.start()

客户端ssdp_client.py:

代码语言:javascript
复制
# -*- coding: utf-8 -*-
import socket
import time
import select
import ssdp_server
SSDP_ADDR = '239.255.255.250'
SSDP_PORT = 1900
MS = 'M-SEARCH * HTTP/1.1\r\nHOST: %s:%d\r\nMAN: "ssdp:discover"\r\nMX: 2\r\nST: ssdp:all\r\n\r\n' \
% (SSDP_ADDR, SSDP_PORT)
class SSDPClient():
def __init__(self):
self.__s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# INFO: 若绑定,服务端收到的是固定的地址和端口号
self.__s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
local_ip = socket.gethostbyname(socket.gethostname())
self.__s.bind((local_ip, 50000))
def start(self):
self.__send_search()
while True:
reads, _, _ = select.select([self.__s], [], [], 5)
if reads:
data, addr = self.__s.recvfrom(2048)
conn = ssdp_server.Connection(self.__s, data, addr)
conn.handle_request()
if conn.is_find_service:
break
else:  # timeout
self.__send_search()
self.__s.close()
def __send_search(self):
print "Sending M-SEARCH..."
# INFO: 发送到SSDP组播地址上
self.__s.sendto(MS, (SSDP_ADDR, SSDP_PORT))
if __name__ == '__main__':
port = SSDPClient()
port.start()

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/183233.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月11日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档