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>", re.S), str(data))[1]
        except TypeError:
            pass
        else:
            # print(data)
            print("IPv4: {}".format(IPv4))
            print("MAC: {}".format(MAC))

代码主要使用了socket发送数据,使用re模块来处理和提取数据。
通过使用wireshark抓包发现,首先需要客户端发送一个xml类型的数据,server端接收到数据后,会返回摄像头的各种信息,包括本文中将要获取的摄像头IPv4和MAC地址。
程序运行结果如图所示:
程序运行结果

写在后面

本程序不仅可以作为设备发现来使用,在更换设备时也能第一时间发现设备是否被更换。

UDP (User Datagram Protocol) 是无连接的协议,并不像TCP那样提供端到端的可靠传输服务。因此,当接收UDP多播数据时,你并不能直接获取发送方的IP地址,因为UDP包头并不包含源IP信息。多播包通常会被网络设备分发给所有已订阅该组播地址的目标主机,而不追踪发送者。 然而,在某些特定的应用场景下,比如使用UDG (User Datagram Gateway) 或者通过一些中间代理服务器,你可以尝试利用这些服务提供的元数据来间接获取发送方的信息。例如,如果服务器维护了一个映射表,将多播地址关联到一组发送者,则可以从这个表中查找。 在编程层面,如果你需要这种高级功能,可以考虑使用支持多播的库或者API,它们可能会提供额外的服务来帮助处理。例如在Python的`socket`模块中,虽然原始的UDP socket无法提供源IP,但有些库如`PyMulticast`可能会记录这样的信息。 ```python import PyMulticast # 创建多播接收器 group = 'your_multicast_address' receiver = PyMulticast.MultiCastReceiver(group) # 注册接收回调 def on_data_received(ip, port, data): print(f"Received from IP: {ip}") receiver.register_callback(on_data_received) receiver.join_group() # 开始接收数据 receiver.run_forever() ``` 在这个例子中,你需要查看`on_data_received`函数中的`ip`参数来获取发送方的IP。但是请注意,这依赖于所使用的库是否提供了这样的功能。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值