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

SSDP协议的Python示例「建议收藏」废话少说,直接上代码。服务端ssdp_server.py

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

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

# -*- 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:

# -*- 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.net/183233.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • matlab aic sic,请教ADF检验时AIC准则和SIC准则不一致时怎么办?

    matlab aic sic,请教ADF检验时AIC准则和SIC准则不一致时怎么办?SIC最小准则下的检验结果如下,显示不能拒绝原假设,即数据有单位根。NullHypothesis:LAUShasaunitrootExogenous:Constant,LinearTrendLagLength:2(AutomaticbasedonSIC,MAXLAG=11)t-StatisticProb.*AugmentedDickey-Fullertes…

    2022年5月10日
    52
  • Java集合篇:ArrayList详解

    Java集合篇:ArrayList详解

    2021年10月4日
    45
  • MySQL配置+SQLyog安装教程

    MySQL配置+SQLyog安装教程一标题、MySQL的配置官网地址:MySQL官网地址。我选择的版本是5.5.27,具体mis文件运行之后的操作步骤参考博客MySQL安装教程。二、SQLyog安装教程安装程序下载:链接:https://pan.baidu.com/s/1MeFavdcOAd0BUG3D9cA9eg提取码:i5mi安装教程参考博客SQLyog安装教程三、所需数据库资源百度云链接:链接:https…

    2022年5月28日
    60
  • JavaCodeTra 猴子选猴王 约瑟夫循环

    JavaCodeTra 猴子选猴王 约瑟夫循环

    2022年2月2日
    61
  • .NET(c#) 移动APP开发平台 – Smobiler(1)

    .NET(c#) 移动APP开发平台 – Smobiler(1)如果说基于.net的移动开发平台,目前比较流行的可能是xamarin了,不过除了这个,还有一个比xamarin更好用的国内的.net移动开发平台,smobiler,不用学习另外一套开发模式或者搭建复杂的开发环境,smobiler能够让大家像开发传统windows一样去开发移动应用,那么列举一下这个平台的特点。1. 基于VisualStudio的可视化开发。如同开发传统Windows平台一样的…

    2022年5月6日
    168
  • nsga2 matlab,NSGA2算法特征选择MATLAB实现(多目标)

    nsga2 matlab,NSGA2算法特征选择MATLAB实现(多目标)利用nsga2进行进行特征选择其主要思想是:将子集的选择看作是一个搜索寻优问题(wrapper方法),生成不同的组合,对组合进行评价,再与其他的组合进行比较。这样就将子集的选择看作是一个是一个优化问题。需要优化的两个目标为特征数和精度。nsga2是一个多目标优化算法。具体的特征选择代码在上述代码的基础上改了两个①主函数②评价函数,增加了一个数据分成训练集和测试集的函数:MATLABfunction…

    2022年5月19日
    41

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号