Onvif开发之客户端搜索篇
关于ONVIF的广播,有客户端搜索和服务端发现的区别:客户端向固定的网段和固定的端口发送广播消息,服务端在对应的端口回复广播请求消息
本文首先介绍客户端如何进行广播的已经对广播回复的信息的基本处理。
客户端这里处理相对服务端比较复杂一点,需要注意几个地方:
1 广播的ip和端口号(注意这个端口号和通信的端口是不一样的,通信端口号可以自己随意定一个,但是这个广播的是ONVIF协议定好公用的)
ip:239:255:255:250 port:3702
2 MessageID ,此ID每次都需要不同,不然每次只有第一次能搜索到设备,第二次就不行了!一般情况下都是区uuid的随机值的,但是我在开发的过程是去的一个随机值加上自己设备的mac地址组合的
3 soap_send___wsdd__Probe函数,发送广播信息,通过它来判断是否发送成功,确认是否继续下一步操作进行接收消息
4 soap_recv___wsdd__ProbeMatches函数,此函数是通过广播后,设备通过onvif协议回复了设备的一些基本信息,客户端通过循 环调用此函数来接多个设备回复的各个设备的一些基本信息包括设备ip以及通信的prot
知道了这几个基本的注意点和前篇介绍的代码生成框架,接下来就是敲代码了。该main函数登场了
- <span style="font-size:14px;">/*
- * =====================================================================================
- *
- * Filename: main.c
- * Description: 简单例程测试:客户端通过ONVIF协议搜索前端设备,
- * Created: 2013年12月26日 12时17分48秒
- * Compiler: gcc
- * Author: max_min_,
- *
- * =====================================================================================
- */
- #include "wsdd.h"
- #include <stdio.h>
- static struct soap* ONVIF_Initsoap(struct SOAP_ENV__Header *header, const char *was_To, const char *was_Action, int timeout)
- {
- struct soap *soap = NULL;
- unsigned char macaddr[6];
- char _HwId[1024];
- unsigned int Flagrand;
- soap = soap_new();
- if(soap == NULL)
- {
- printf("[%d]soap = NULL\n", __LINE__);
- return NULL;
- }
- soap_set_namespaces( soap, namespaces);
- //超过5秒钟没有数据就退出
- if (timeout > 0)
- {
- soap->recv_timeout = timeout;
- soap->send_timeout = timeout;
- soap->connect_timeout = timeout;
- }
- else
- {
- //如果外部接口没有设备默认超时时间的话,我这里给了一个默认值10s
- soap->recv_timeout = 10;
- soap->send_timeout = 10;
- soap->connect_timeout = 10;
- }
- soap_default_SOAP_ENV__Header(soap, header);
- // 为了保证每次搜索的时候MessageID都是不相同的!因为简单,直接取了随机值
- srand((int)time(0));
- Flagrand = rand()%9000 + 1000; //保证四位整数
- macaddr[0] = 0x1; macaddr[1] = 0x2; macaddr[2] = 0x3; macaddr[3] = 0x4; macaddr[4] = 0x5; macaddr[5] = 0x6;
- sprintf(_HwId,"urn:uuid:%ud68a-1dd2-11b2-a105-%02X%02X%02X%02X%02X%02X",
- Flagrand, macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]);
- header->wsa__MessageID =(char *)malloc( 100);
- memset(header->wsa__MessageID, 0, 100);
- strncpy(header->wsa__MessageID, _HwId, strlen(_HwId));
- if (was_Action != NULL)
- {
- header->wsa__Action =(char *)malloc(1024);
- memset(header->wsa__Action, '\0', 1024);
- strncpy(header->wsa__Action, was_Action, 1024);//"http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe";
- }
- if (was_To != NULL)
- {
- header->wsa__To =(char *)malloc(1024);
- memset(header->wsa__To, '\0', 1024);
- strncpy(header->wsa__To, was_To, 1024);//"urn:schemas-xmlsoap-org:ws:2005:04:discovery";
- }
- soap->header = header;
- return soap;
- }
- int ONVIF_ClientDiscovery( )
- {
- int HasDev = 0;
- int retval = SOAP_OK;
- wsdd__ProbeType req;
- struct __wsdd__ProbeMatches resp;
- wsdd__ScopesType sScope;
- struct SOAP_ENV__Header header;
- struct soap* soap;
- const char *was_To = "urn:schemas-xmlsoap-org:ws:2005:04:discovery";
- const char *was_Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe";
- //这个就是传递过去的组播的ip地址和对应的端口发送广播信息
- const char *soap_endpoint = "soap.udp://239.255.255.250:3702/";
- //这个接口填充一些信息并new返回一个soap对象,本来可以不用额外接口,
- // 但是后期会作其他操作,此部分剔除出来后面的操作就相对简单了,只是调用接口就好
- soap = ONVIF_Initsoap(&header, was_To, was_Action, 5);
- soap_default_SOAP_ENV__Header(soap, &header);
- soap->header = &header;
- soap_default_wsdd__ScopesType(soap, &sScope);
- sScope.__item = "";
- soap_default_wsdd__ProbeType(soap, &req);
- req.Scopes = &sScope;
- req.Types = ""; //"dn:NetworkVideoTransmitter";
- retval = soap_send___wsdd__Probe(soap, soap_endpoint, NULL, &req);
- //发送组播消息成功后,开始循环接收各位设备发送过来的消息
- while (retval == SOAP_OK)
- {
- retval = soap_recv___wsdd__ProbeMatches(soap, &resp);
- if (retval == SOAP_OK)
- {
- if (soap->error)
- {
- printf("[%d]: recv error:%d,%s,%s\n", __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
- retval = soap->error;
- }
- else //成功接收某一个设备的消息
- {
- HasDev ++;
- if (resp.wsdd__ProbeMatches->ProbeMatch != NULL && resp.wsdd__ProbeMatches->ProbeMatch->XAddrs != NULL)
- {
- printf(" ################ recv %d devices info #### \n", HasDev );
- printf("Target Service Address : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->XAddrs);
- printf("Target EP Address : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.Address);
- printf("Target Type : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->Types);
- printf("Target Metadata Version : %d\r\n", resp.wsdd__ProbeMatches->ProbeMatch->MetadataVersion);
- sleep(1);
- }
- }
- }
- else if (soap->error)
- {
- if (HasDev == 0)
- {
- printf("[%s][%d] Thers Device discovery or soap error: %d, %s, %s \n", __func__, __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstrin
- retval = soap->error;
- }
- else
- {
- printf(" [%s]-[%d] Search end! It has Searched %d devices! \n", __func__, __LINE__, HasDev);
- retval = 0;
- }
- break;
- }
- }
- soap_destroy(soap);
- soap_end(soap);
- soap_free(soap);
- return retval;
- }
- int main(void )
- {
- //组播接口
- if (ONVIF_ClientDiscovery() != 0 )
- {
- printf("discovery failed!\n");
- return -1;
- }
- return 0;
- }
- </span>
运行测试结果如下图
可以看到注意信息就是http://172.18.13.127:9000/onvif/device_service这句了!设备的IP地址以及通信端口都有了,第三个没有端口,也就是使用默认的端口80了,海康和大华的貌似都是用80端口
到这里差不多客户端的搜索就完成了,剩下只是把搜索到的设备信息解析出来,然后保存起来!提供给客户端使用了,我在实际开发的过程中是通过调用外层接口传递一个回调函数指针进去,然后匹配信息出来,给客户端!
搜索使用的源码下载地址:onvif客户端搜索
Onvif开发之客户端搜索篇的更多相关文章
- Onvif开发之客户端鉴权获取参数篇
前面一篇已经介绍了客户端如何发些设备,下面这篇简单介绍下在发现设备后,如何通过ONVIF协议来获取设备的相关参数 ONVIF中不管是客户端还是设备端,最先实现的接口都是关于能力的那个接口,在客户端实现 ...
- Jsoup开发网站客户端第二篇,图片轮播,ScrollView兼容ListView
最近一段日子忙的焦头烂额,代码重构,新项目编码,导致jsoup开发网站客户端也没时间继续下去,只能利用晚上时间去研究了.今天实现美食网首页图片轮播效果,网站效果图跟Android客户端实现如图: 从浏 ...
- Onvif开发之基础介绍篇
什么是Onvif协议,谁开启了Onvif时代? ONVIF:原意为 开放型网络视频接口论坛,即 Open Network Video Interface Forum ,是安讯士.博世.索尼等三家公司在 ...
- ONVIF客户端搜索设备获取rtsp地址开发笔记(精华篇)
原文 http://blog.csdn.net/gubenpeiyuan/article/details/25618177 概要: 目前ONVIF协议家族设备已占据数字监控行业半壁江山以上,亲, ...
- 【视频开发】ONVIF客户端搜索设备获取rtsp地址开发笔记(精华篇)
转载地址:http://blog.csdn.net/gubenpeiyuan/article/details/25618177 概要: 目前ONVIF协议家族设备已占据数字监控行业 ...
- onvif开发之设备发现功能的实现--转
忙了一个多月,onvif总算告一段落了.这几个星期忙着其他的项目,也没有好好整理一下onvif的东西.接下来得好好整理一下自己的项目思路和项目经验,同时将自己的一些心得写出来,希望对人有所帮助. 相信 ...
- Python开发【第二十一篇】:Web框架之Django【基础】
Python开发[第二十一篇]:Web框架之Django[基础] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5237704.html Python之 ...
- Python开发【第二十篇】:缓存
Python开发[第二十篇]:缓存redis&Memcache 点击这里 Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy ...
- Struts 2.x仍然明显落后于时代。 Struts 2.x这一类老牌Web MVC开发框架仅能用于开发瘦客户端应用,无法用来开发对于交互体验要求更高的应用。
后来我在工作中陆续使用过Struts 1.x和Struts 2.x.我曾经把一个开源的基于Struts 1.x的自助式广告联盟应用移植到Spring MVC,还基于Struts 2.x做过网站开发.S ...
随机推荐
- FLUME KAFKA SOURCE 和 SINK 使用同一个 TOPIC
FLUME KAFKA SOURCE 和 SINK 使用同一个 TOPIC 最近做了一个事情,过滤下kakfa中的数据后,做这个就用到了flume,直接使用flume source 和 flume s ...
- windows server 2012安装.NET3.5安装提示需要指定源路径 安装.net3.5提示安装不成功,提示需要指定源路径。
安装.net3.5提示安装不成功,提示需要指定源路径. 正确的操作步骤: 1.需要下载windows server 2012操作系统盘.用解压工具解压出来. 2012操作系统下载地址: ...
- 洛谷1034 NOIP2002 矩形覆盖
问题描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7). 这些点可以 ...
- Bash 基础特性
命令别名 alias 显示当前shell中定义的所有别名 alias 别名='原始命令' unalias 别名 取消定义的别名在命令前加\使用命令本身,而不是别名(或者使用绝对路径执行命令使用命 ...
- caioj 1111 树形动态规划(TreeDP)6: 皇宫看守 (状态设计)
这道题的难点在于状态怎么设计 这道题要求全部都是安全的,所以我们做的时候自底向上每一个结点都要是安全的 结合前一题当前结点选和不选,我们可以分出四种情况出来 选 安全 选 不安全 不选 安全 不选 不 ...
- java流1----InputStream、OutputStream、Reader、Writer
字节流和字符流 顾名思义,字节流就是操作的是字节,字符流操作的就是字符.其中字节流又可以分为字节输入流(InputStream)和字节输出流(OutputStream).同样的字符流也可以分为字符输入 ...
- 今天听说了一个压缩解压整型的方式-group-varint
group varint https://github.com/facebook/folly/blob/master/folly/docs/GroupVarint.md 这个是facebook的实现 ...
- MyEclipse连接不上genymotion的解决方式
奇怪的是我的MyEclipse有时候连接得上genymotion,有时候又连接不上.之前连接不上的时候,就直接用真机调试,因此出现这个问题非常久了一直都没有去找解决方式.今天认真的反省了自己,再也不能 ...
- type 'simple Class' does not conform to protocol 'Example Protocol'错误
在看swift教程中"接口和扩展"这小部分. 在编写时提示"type 'simple Class' does not conform to protocol 'Examp ...
- CentOS 搭建 Mysql MMM 高可用架构
环境 CentOS Mysql 5.1 前提 安装了EPEL,详细安装步骤请參照 http://blog.csdn.net/robinsonmhj/article/details/36184863 机 ...