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)
上一篇 2022年10月11日 上午11:00
下一篇 2022年10月11日 上午11:16


相关推荐

  • idea2021.11.1激活码_最新在线免费激活

    (idea2021.11.1激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月28日
    52
  • linux中运行bminer,ETH/ETC挖矿教程:Bminer & Ethminer

    linux中运行bminer,ETH/ETC挖矿教程:Bminer & Ethminer一、操作系统:windowsLinux二、挖矿软件:Bminer(N卡)Ethminer(N卡/A卡)三、挖矿教程:bminer使用教程1.解压压缩包2.修改mine.bat右键点击mine.bat->编辑->删除所有原文件内容->将下方内容粘贴至文件@echoOFFSETADDRESS=__需要修改__SETUSERNAME=%ADDRESS%.__需要修改__SET…

    2022年10月15日
    5
  • 常见的计算机病毒种类有,五种常见的计算机病毒种类有哪些

    常见的计算机病毒种类有,五种常见的计算机病毒种类有哪些五种常见的计算机病毒种类有系统病毒、蠕虫病毒、木马病毒、脚本病毒、宏病毒。计算机病毒(ComputerVirus)是编制者在计算机程序中插入的破坏计算机功能或者数据的代码,能影响计算机使用,能自我复制的一组计算机指令或者程序代码。计算机病毒是人为制造的,有破坏性,又有传染性和潜伏性的,对计算机信息或系统起破坏作用的程序。它不是独立存在的,而是隐蔽在其他可执行的程序之中。计算机中病毒后,轻则影响机…

    2022年5月3日
    64
  • Java图形用户界面设计音乐播放器

    Java图形用户界面设计音乐播放器Java 图形用户界面设计音乐播放器设计思路音乐播放器的基础是可以播放音乐 所以要有一个实现播放音乐功能的类 audioplay 图形界面就是通过动作调用 audioplay 里面的函数 关于实现播放器图形界面的步骤是 先设计好软件界面 再去添加监听器 实现播放 暂停 上一首 下一首 循环播放 导入音乐 播放音乐等功能 我参考的是音乐的软件界面 实现音乐播放的基本功能 并添加新功能 实现界面 实现步骤 设计一个完整的播放器界面 并添加按钮响应播放器界面的背景用的是音乐的背景需要的控件有

    2026年3月17日
    2
  • js获取url参数值的两种方式

    js获取url参数值的两种方式js 获取 url 参数值的两种方式方式一 functionGetQ name varreg newRegExp amp name amp amp i varr window location search substr 1 match reg 获

    2026年3月16日
    2
  • hdu 4885 TIANKENG’s travel(bfs)

    hdu 4885 TIANKENG’s travel(bfs)

    2021年12月6日
    44

发表回复

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

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