python DLNA發現 M-SEARCH

#*- coding:utf-8-*-
import socket, time,os,sys, re, traceback

def sStr(s,s1,s2):
    #if isinstance(s,bytes):s=s.decode('utf-8')
    res_tr = r''+s1+'(.*?)'+s2+''
    ss=re.findall(res_tr, s, re.S|re.M | re.IGNORECASE)
    return None if(None==ss)or(len(ss)<1) else ss[0].strip()

def discover():
    ANY     = "0.0.0.0"
    host    = "239.255.255.250"
    port    = 1900
    tarAddr = (host, port)
    ipRange = socket.inet_aton(host) + socket.inet_aton(ANY)
    cmdSDP  = "M-SEARCH * HTTP/1.1\r\n" \
        "MX: 5\r\n" \
        "ST: upnp:rootdevice\r\n" \
        "MAN: \"ssdp:discover\"\r\n" \
        "Connection: close\r\n" \
        "Host: {}:{}\r\n" \
        "User-Agent: iOS/11.0 UPnP/1.0 DLNADOC/1.50\r\n" \
        "\r\n".format(host,port).encode('UTF-8')

    sck = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,socket.IPPROTO_UDP)
    sck.settimeout(1)
    sck.bind(('0.0.0.0', 1900)) #接收要使用
    sck.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, ipRange)
    sck.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
    ix = 0       #超時多少次,停止接收
    ic = 0       #找到多少個,停止接收
    locations=[] #過濾重複使用
    try:
        sent= sck.sendto(cmdSDP, tarAddr)
        while True:
            try:
                data, addr = sck.recvfrom(1024)
                if (None==data)or(len(data)<10):
                    continue
                s = data.decode("utf-8")
                if s.startswith("M-SEARCH *"):continue  #收到“搜索”命令,忽略
                location = sStr(s, 'location:', '\r\n') #提取值
                usn      = sStr(s, 'USN:', '\r\n')
                server   = sStr(s, 'SERVER:', '\r\n')
                if None==location:
                    print(s)
                    continue
                elif location in locations:
                    continue
                locations.append(location) #過濾重複
                print(" location=%s\n      usn=%s"%(location, usn) )
                print("------------------------------------------------")
                ic+=1
                if ic==18: break #找到多少個,停止接收
            except socket.timeout:
                ix+=1
                if ix==10: break
                time.sleep(0.002)
            except Exception as ex:
                traceback.print_exc()
    except Exception as ex:
        print(ex)
    finally:
        sck.close()

 

#python udp socket

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章