当前位置:   article > 正文

从零开始精通Onvif之设备发现_python 使用多播模式 发现onvif设备

python 使用多播模式 发现onvif设备

设备发现的意义

        在复杂的网络环境中,如何快速而准确地识别网络上的Onvif设备,对于摄像头厂商、系统集成商、开发人员乃至最终用户来说,都显得至关重要。

        首先,设备发现有效简化了集成的复杂度。在没有统一标准之前,每个厂商的设备可能使用私有协议,使得系统集成商在集成多品牌设备时,需要针对每种设备开发特定的接口和配置工具。Onvif设备发现机制简化了这一过程,使得我们能够使用统一的方法发现和配置网络中任何支持Onvif的设备,大大降低了集成的复杂度和成本。

        其次,设备发现大大提升了系统部署的效率。自动化的设备发现机制允许系统自动识别网络中的新设备,减少了手动配置的工作量。尤其是在大型分布式的监控系统中,这一特性尤为重要,可以显著加快系统部署和维护的速度。

        最后,设备发现适应了未来的发展趋势。随着物联网(IoT)、人工智能(AI)、云计算等技术的蓬勃发展,Onvif设备发现机制为这些技术的融合提供了基础,使得安防系统能够更加智能、高效地融入更广泛的智能生态系统中。

设备发现的原理

        Onvif设备发现主要基于WS-Discovery(英文全称为:Web Services Dynamic Discovery)机制。WS-Discovery是一个用于在网络中动态发现Web服务的协议,它允许设备在不需要预先知道对方IP地址或服务URL的情况下,就能够相互发现和通信。

        在Onvif设备发现的过程中,客户端会首先发送一个Probe报文到预定义的组播地址。组播地址通常是239.255.255.250,端口为3702。Probe报文包含了客户端想要查询的Onvif设备的类型,可能还有版本信息。网络中的Onvif设备在接收到这个报文后,会检查报文中的设备类型和版本信息是否与自己匹配。如果匹配,则会向客户端返回一个ProbeMatches报文,其中包含了设备的描述信息和网络地址。客户端在收到这个报文后,就可以解析出设备的网络地址,从而完成设备发现的过程。

设备发现的实现

        Onvif设备发现主要遵循WS-Discovery协议,该协议定义了如何在网络上广播和监听服务的存在。设备发现主要有4个步骤,具体如下。

        1、构造消息。客户端首先构造一个消息,该消息包含所寻找服务的类型,比如:Onvif设备服务。在WS-Discovery中,这通常是一个Probe请求消息,包含了服务类型相匹配的XML描述。

        在下面的Probe请求消息报文中,我们展示了WS-Discovery的基本格式,包括:信封(Envelope)、头部(Header,此处为空)、主体(Body)以及Probe元素。Probe元素中包含了要查找的服务类型,这里是dn:NetworkVideoTransmitter,表示网络视频传输设备。

  1. <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  2. <s:Header />
  3. <s:Body>
  4. <Probe xmlns="http://schemas.xmlsoap.org/ws/2005/04/discovery">
  5. <d:Types xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery">dn:NetworkVideoTransmitter</d:Types>
  6. </Probe>
  7. </s:Body>
  8. </s:Envelope>

        2、发送请求。客户端通过UDP多播地址239.255.255.250(端口号为3702)发送这个消息到网络上,多播地址确保了消息能到达子网内的所有设备,而不仅仅是特定目标地址的设备。具体的代码逻辑,可以参考下面的Python示例代码。

  1. import socket
  2. import struct
  3. from xml.etree import ElementTree as ET
  4. # 构建Probe请求消息报文
  5. def build_probe_message():
  6. envelope = ET.Element('s:Envelope', {'xmlns:s': 'http://www.w3.org/2003/05/soap-envelope'})
  7. header = ET.SubElement(envelope, 's:Header')
  8. body = ET.SubElement(envelope, 's:Body')
  9. probe = ET.SubElement(body, 'Probe', {'xmlns': 'http://schemas.xmlsoap.org/ws/2005/04/discovery'})
  10. probe_match = ET.SubElement(probe, 'd:Types', {'xmlns:d': 'http://schemas.xmlsoap.org/ws/2005/04/discovery'}).text = 'dn:NetworkVideoTransmitter'
  11. return ET.tostring(envelope)
  12. # 发送多播请求
  13. def send_discovery_request():
  14. multicast_ip = "239.255.255.250"
  15. port = 3702
  16. message = build_probe_message()
  17. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  18. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  19. sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, struct.pack('b', 4))
  20. sock.sendto(message, (multicast_ip, port))
  21. sock.close()
  22. # 主函数
  23. if __name__ == "__main__":
  24. send_discovery_request()
  25. print("Discovery request sent.")

        3、等待响应。符合服务类型要求的Onvif设备作为服务端,在接收到请求后,会回复一个包含其设备描述信息的ProbeMatch响应消息。响应中通常包括:设备的URN(即Uniform Resource Name)、服务端点URL、设备型号、制造商信息等。

        在下面的ProbeMatch响应消息报文中,ProbeMatch元素包含了设备的端点引用(EndpointReference)、服务类型(Types)、作用域范围(Scopes)、服务地址(XAddrs,通常指向设备的Onvif服务地址)以及元数据版本(MetadataVersion)等。

  1. <s:Envelope ...>
  2. <s:Header />
  3. <s:Body>
  4. <ProbeMatch ...>
  5. <EndpointReference ...>
  6. <Address>urn:uuid:...设备唯一ID...</Address>
  7. </EndpointReference>
  8. <Types>dn:NetworkVideoTransmitter</Types>
  9. <Scopes />
  10. <XAddrs>http://设备IP/onvif/device_service</XAddrs>
  11. <MetadataVersion>1</MetadataVersion>
  12. ...
  13. </ProbeMatch>
  14. </s:Body>
  15. </s:Envelope>

        4、解析响应。客户端解析收到的响应信息,根据需要选择合适的设备。然后,通过设备提供的服务端点URL建立后续的SOAP通信,进行设备的配置、控制等其他操作。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号