python3通過udp實現(xiàn)組播數(shù)據(jù)的發(fā)送和接收操作
本文主要通過對??禂z像頭進(jìn)行抓包,模擬發(fā)送了udp包,并抓取攝像頭返回的數(shù)據(jù)包,解析并提取相關(guān)信息。
通過抓包發(fā)現(xiàn),海康攝像頭發(fā)送、接收數(shù)據(jù)使用udp協(xié)議,后來比較發(fā)現(xiàn),使用python模擬起來比較簡單。由于攝像頭內(nèi)置了udp協(xié)議的server端程序,本文主要使用python模擬客戶端發(fā)送udp數(shù)據(jù)包。
客戶端代碼
import socket import re ANY = "0.0.0.0" DES_IP = "239.255.255.250" PORT = 37020 # xml_str = b'<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>B2D5D4D2-808C-40F6-87CD-694C05C2B274</Uuid><Types>inquiry</Types></Probe> ' xml_str = b'<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>CB09F608-E016-4EE8-869A-CA186852F12E</Uuid><Types>inquiry</Types></Probe> ' # 創(chuàng)建UDP socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # 允許端口復(fù)用 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 綁定監(jiān)聽多播數(shù)據(jù)包的端口 s.bind((ANY, PORT)) # 聲明該socket為多播類型 s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255) # 加入多播組,組地址由第三個參數(shù)制定 s.setsockopt( socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(DES_IP) + socket.inet_aton(ANY) ) s.setblocking(False) s.sendto(xml_str, (DES_IP, PORT)) while True: try: data, address = s.recvfrom(2048) except Exception as e: # print(e) pass else: print(address) # print(data) try: IPv4 = re.search(re.compile(r"<IPv4Address>(.*?)</IPv4Address>", re.S), str(data))[1] MAC = re.search(re.compile(r"<MAC>(.*?)</MAC>", re.S), str(data))[1] except TypeError: pass else: # print(data) print("IPv4: {}".format(IPv4)) print("MAC: {}".format(MAC))
代碼主要使用了socket發(fā)送數(shù)據(jù),使用re模塊來處理和提取數(shù)據(jù)。
通過使用wireshark抓包發(fā)現(xiàn),首先需要客戶端發(fā)送一個xml類型的數(shù)據(jù),server端接收到數(shù)據(jù)后,會返回攝像頭的各種信息,包括本文中將要獲取的攝像頭IPv4和MAC地址。
程序運(yùn)行結(jié)果如圖所示:
寫在后面
本程序不僅可以作為設(shè)備發(fā)現(xiàn)來使用,在更換設(shè)備時也能第一時間發(fā)現(xiàn)設(shè)備是否被更換。
補(bǔ)充知識:python3 udp可以發(fā)送但不能接收消息的解決方法
現(xiàn)在有兩個系統(tǒng),win10和虛擬機(jī)中的xp,win10中有python3,xp中有網(wǎng)絡(luò)調(diào)試助手。
python3通過udp方式發(fā)送的消息可以在網(wǎng)絡(luò)調(diào)試助手接收,但是在網(wǎng)絡(luò)調(diào)試助手上發(fā)送的消息在python3上卻接收不到。首先python3接收寫的代碼如下:
import socket def receive_message(): udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #創(chuàng)建一個套接字 udp_socket.bind(('', 63630)) #綁定本地信息,自己電腦的ip和程序的端口。ip一般不用寫,表示本機(jī)的任意一個ip,端口大于常用的1023就可以 while True: udp_data = udp_socket.recvfrom(1024) #接收數(shù)據(jù),1024表示本次接收的最大字節(jié)數(shù) if udp_data[0].decode(encoding='gbk') != 'end': print('{}:{}'.format(str(udp_data[1]), udp_data[0].decode(encoding='gbk'))) else: break udp_socket.close() #關(guān)閉套接字 if __name__ == '__main__': receive_message()
本以為是程序的問題或者是網(wǎng)絡(luò)調(diào)試助手的問題,但是檢查多遍后再次嘗試仍然無法接收。。暫時放下。。
今天把win10防火墻關(guān)閉后發(fā)現(xiàn)是可以正常接收的,但是想在不關(guān)閉防火墻的情況下仍然能夠接收,百度也沒有找到想要的答案。。
正當(dāng)要放棄的時候看到如下設(shè)置:
于是勾選上了紅色箭頭所指的復(fù)選框。
再次運(yùn)行程序,win10彈出對話框如下:
點(diǎn)擊允許訪問后,在xp網(wǎng)絡(luò)調(diào)試助手上發(fā)送消息就可以在python3上正常接收了!!!
以上這篇python3通過udp實現(xiàn)組播數(shù)據(jù)的發(fā)送和接收操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
python包裝和授權(quán)學(xué)習(xí)教程
包裝是指對一個已經(jīng)存在的對象進(jìn)行系定義加工,實現(xiàn)授權(quán)是包裝的一個特性,下面這篇文章主要給大家介紹了關(guān)于python包裝和授權(quán)的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06jupyter notebook 恢復(fù)誤刪單元格或者歷史代碼的實現(xiàn)
這篇文章主要介紹了jupyter notebook 恢復(fù)誤刪單元格或者歷史代碼的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04pytorch Dataset,DataLoader產(chǎn)生自定義的訓(xùn)練數(shù)據(jù)案例
這篇文章主要介紹了pytorch Dataset, DataLoader產(chǎn)生自定義的訓(xùn)練數(shù)據(jù)案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03Python函數(shù)的參數(shù)常見分類與用法實例詳解
這篇文章主要介紹了Python函數(shù)的參數(shù)常見分類與用法,結(jié)合實例形式較為詳細(xì)的分析了Python函數(shù)的形參、實參、默認(rèn)參數(shù)、可變參數(shù)等概念、使用方法及相關(guān)操作注意事項,需要的朋友可以參考下2019-03-03