1. 程式人生 > 程式設計 >python3通過udp實現組播資料的傳送和接收操作

python3通過udp實現組播資料的傳送和接收操作

本文主要通過對海康攝像頭進行抓包,模擬傳送了udp包,並抓取攝像頭返回的資料包,解析並提取相關資訊。

通過抓包發現,海康攝像頭髮送、接收資料使用udp協議,後來比較發現,使用python模擬起來比較簡單。由於攝像頭內建了udp協議的server端程式,本文主要使用python模擬客戶端傳送udp資料包。

客戶端程式碼

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> '

# 建立UDP socket
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,socket.IPPROTO_UDP)
# 允許埠複用
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# 繫結監聽多播資料包的埠
s.bind((ANY,PORT))
# 宣告該socket為多播型別
s.setsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_TTL,255)
# 加入多播組,組地址由第三個引數制定
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>",str(data))[1]
    except TypeError:
      pass
    else:
      # print(data)
      print("IPv4: {}".format(IPv4))
      print("MAC: {}".format(MAC))

程式碼主要使用了socket傳送資料,使用re模組來處理和提取資料。

通過使用wireshark抓包發現,首先需要客戶端傳送一個xml型別的資料,server端接收到資料後,會返回攝像頭的各種資訊,包括本文中將要獲取的攝像頭IPv4和MAC地址。

程式執行結果如圖所示:

python3通過udp實現組播資料的傳送和接收操作

寫在後面

本程式不僅可以作為裝置發現來使用,在更換裝置時也能第一時間發現裝置是否被更換。

補充知識:python3 udp可以傳送但不能接收訊息的解決方法

現在有兩個系統,win10和虛擬機器中的xp,win10中有python3,xp中有網路除錯助手。

python3通過udp方式傳送的訊息可以在網路除錯助手接收,但是在網路除錯助手上傳送的訊息在python3上卻接收不到。首先python3接收寫的程式碼如下:

import socket

def receive_message():
  udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #建立一個套接字
  udp_socket.bind(('',63630)) #繫結本地資訊,自己電腦的ip和程式的埠。ip一般不用寫,表示本機的任意一個ip,埠大於常用的1023就可以
  while True:
    udp_data = udp_socket.recvfrom(1024) #接收資料,1024表示本次接收的最大位元組數
    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() #關閉套接字

if __name__ == '__main__':
  receive_message()

本以為是程式的問題或者是網路除錯助手的問題,但是檢查多遍後再次嘗試仍然無法接收。。暫時放下。。

今天把win10防火牆關閉後發現是可以正常接收的,但是想在不關閉防火牆的情況下仍然能夠接收,百度也沒有找到想要的答案。。

正當要放棄的時候看到如下設定:

python3通過udp實現組播資料的傳送和接收操作

於是勾選上了紅色箭頭所指的複選框。

再次執行程式,win10彈出對話方塊如下:

python3通過udp實現組播資料的傳送和接收操作

點選允許訪問後,在xp網路除錯助手上傳送訊息就可以在python3上正常接收了!!!

以上這篇python3通過udp實現組播資料的傳送和接收操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。