从零开始精通Onvif之设备发现

2024-06-06 10:12

本文主要是介绍从零开始精通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,表示网络视频传输设备。

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

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

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

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

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

<s:Envelope ...><s:Header /><s:Body><ProbeMatch ...><EndpointReference ...><Address>urn:uuid:...设备唯一ID...</Address></EndpointReference><Types>dn:NetworkVideoTransmitter</Types><Scopes /><XAddrs>http://设备IP/onvif/device_service</XAddrs><MetadataVersion>1</MetadataVersion>...</ProbeMatch></s:Body>
</s:Envelope>

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

这篇关于从零开始精通Onvif之设备发现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1035812

相关文章

Linux之platform平台设备驱动详解

《Linux之platform平台设备驱动详解》Linux设备驱动模型中,Platform总线作为虚拟总线统一管理无物理总线依赖的嵌入式设备,通过platform_driver和platform_de... 目录platform驱动注册platform设备注册设备树Platform驱动和设备的关系总结在 l

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二

从入门到精通MySQL联合查询

《从入门到精通MySQL联合查询》:本文主要介绍从入门到精通MySQL联合查询,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下... 目录摘要1. 多表联合查询时mysql内部原理2. 内连接3. 外连接4. 自连接5. 子查询6. 合并查询7. 插入查询结果摘要前面我们学习了数据库设计时要满

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

Oracle 数据库数据操作如何精通 INSERT, UPDATE, DELETE

《Oracle数据库数据操作如何精通INSERT,UPDATE,DELETE》在Oracle数据库中,对表内数据进行增加、修改和删除操作是通过数据操作语言来完成的,下面给大家介绍Oracle数... 目录思维导图一、插入数据 (INSERT)1.1 插入单行数据,指定所有列的值语法:1.2 插入单行数据,指

MySQL DQL从入门到精通

《MySQLDQL从入门到精通》通过DQL,我们可以从数据库中检索出所需的数据,进行各种复杂的数据分析和处理,本文将深入探讨MySQLDQL的各个方面,帮助你全面掌握这一重要技能,感兴趣的朋友跟随小... 目录一、DQL 基础:SELECT 语句入门二、数据过滤:WHERE 子句的使用三、结果排序:ORDE

详解如何使用Python从零开始构建文本统计模型

《详解如何使用Python从零开始构建文本统计模型》在自然语言处理领域,词汇表构建是文本预处理的关键环节,本文通过Python代码实践,演示如何从原始文本中提取多尺度特征,并通过动态调整机制构建更精确... 目录一、项目背景与核心思想二、核心代码解析1. 数据加载与预处理2. 多尺度字符统计3. 统计结果可

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I