关于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函数登场了

  1. <span style="font-size:14px;">/*
  2. * =====================================================================================
  3. *
  4. *       Filename:  main.c
  5. *    Description:  简单例程测试:客户端通过ONVIF协议搜索前端设备,
  6. *        Created:  2013年12月26日 12时17分48秒
  7. *       Compiler:  gcc
  8. *         Author:  max_min_,
  9. *
  10. * =====================================================================================
  11. */
  12. #include "wsdd.h"
  13. #include <stdio.h>
  14. static struct soap* ONVIF_Initsoap(struct SOAP_ENV__Header *header, const char *was_To, const char *was_Action, int timeout)
  15. {
  16. struct soap *soap = NULL;
  17. unsigned char macaddr[6];
  18. char _HwId[1024];
  19. unsigned int Flagrand;
  20. soap = soap_new();
  21. if(soap == NULL)
  22. {
  23. printf("[%d]soap = NULL\n", __LINE__);
  24. return NULL;
  25. }
  26. soap_set_namespaces( soap, namespaces);
  27. //超过5秒钟没有数据就退出
  28. if (timeout > 0)
  29. {
  30. soap->recv_timeout = timeout;
  31. soap->send_timeout = timeout;
  32. soap->connect_timeout = timeout;
  33. }
  34. else
  35. {
  36. //如果外部接口没有设备默认超时时间的话,我这里给了一个默认值10s
  37. soap->recv_timeout    = 10;
  38. soap->send_timeout    = 10;
  39. soap->connect_timeout = 10;
  40. }
  41. soap_default_SOAP_ENV__Header(soap, header);
  42. // 为了保证每次搜索的时候MessageID都是不相同的!因为简单,直接取了随机值
  43. srand((int)time(0));
  44. Flagrand = rand()%9000 + 1000; //保证四位整数
  45. macaddr[0] = 0x1; macaddr[1] = 0x2; macaddr[2] = 0x3; macaddr[3] = 0x4; macaddr[4] = 0x5; macaddr[5] = 0x6;
  46. sprintf(_HwId,"urn:uuid:%ud68a-1dd2-11b2-a105-%02X%02X%02X%02X%02X%02X",
  47. Flagrand, macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]);
  48. header->wsa__MessageID =(char *)malloc( 100);
  49. memset(header->wsa__MessageID, 0, 100);
  50. strncpy(header->wsa__MessageID, _HwId, strlen(_HwId));
  51. if (was_Action != NULL)
  52. {
  53. header->wsa__Action =(char *)malloc(1024);
  54. memset(header->wsa__Action, '\0', 1024);
  55. strncpy(header->wsa__Action, was_Action, 1024);//"http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe";
  56. }
  57. if (was_To != NULL)
  58. {
  59. header->wsa__To =(char *)malloc(1024);
  60. memset(header->wsa__To, '\0', 1024);
  61. strncpy(header->wsa__To,  was_To, 1024);//"urn:schemas-xmlsoap-org:ws:2005:04:discovery";
  62. }
  63. soap->header = header;
  64. return soap;
  65. }
  66. int ONVIF_ClientDiscovery( )
  67. {
  68. int HasDev = 0;
  69. int retval = SOAP_OK;
  70. wsdd__ProbeType req;
  71. struct __wsdd__ProbeMatches resp;
  72. wsdd__ScopesType sScope;
  73. struct SOAP_ENV__Header header;
  74. struct soap* soap;
  75. const char *was_To = "urn:schemas-xmlsoap-org:ws:2005:04:discovery";
  76. const char *was_Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe";
  77. //这个就是传递过去的组播的ip地址和对应的端口发送广播信息
  78. const char *soap_endpoint = "soap.udp://239.255.255.250:3702/";
  79. //这个接口填充一些信息并new返回一个soap对象,本来可以不用额外接口,
  80. // 但是后期会作其他操作,此部分剔除出来后面的操作就相对简单了,只是调用接口就好
  81. soap = ONVIF_Initsoap(&header, was_To, was_Action, 5);
  82. soap_default_SOAP_ENV__Header(soap, &header);
  83. soap->header = &header;
  84. soap_default_wsdd__ScopesType(soap, &sScope);
  85. sScope.__item = "";
  86. soap_default_wsdd__ProbeType(soap, &req);
  87. req.Scopes = &sScope;
  88. req.Types = ""; //"dn:NetworkVideoTransmitter";
  89. retval = soap_send___wsdd__Probe(soap, soap_endpoint, NULL, &req);
  90. //发送组播消息成功后,开始循环接收各位设备发送过来的消息
  91. while (retval == SOAP_OK)
  92. {
  93. retval = soap_recv___wsdd__ProbeMatches(soap, &resp);
  94. if (retval == SOAP_OK)
  95. {
  96. if (soap->error)
  97. {
  98. printf("[%d]: recv error:%d,%s,%s\n", __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
  99. retval = soap->error;
  100. }
  101. else //成功接收某一个设备的消息
  102. {
  103. HasDev ++;
  104. if (resp.wsdd__ProbeMatches->ProbeMatch != NULL && resp.wsdd__ProbeMatches->ProbeMatch->XAddrs != NULL)
  105. {
  106. printf(" ################  recv  %d devices info #### \n", HasDev );
  107. printf("Target Service Address  : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->XAddrs);
  108. printf("Target EP Address       : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.Address);
  109. printf("Target Type             : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->Types);
  110. printf("Target Metadata Version : %d\r\n", resp.wsdd__ProbeMatches->ProbeMatch->MetadataVersion);
  111. sleep(1);
  112. }
  113. }
  114. }
  115. else if (soap->error)
  116. {
  117. if (HasDev == 0)
  118. {
  119. printf("[%s][%d] Thers Device discovery or soap error: %d, %s, %s \n", __func__, __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstrin
  120. retval = soap->error;
  121. }
  122. else
  123. {
  124. printf(" [%s]-[%d] Search end! It has Searched %d devices! \n", __func__, __LINE__, HasDev);
  125. retval = 0;
  126. }
  127. break;
  128. }
  129. }
  130. soap_destroy(soap);
  131. soap_end(soap);
  132. soap_free(soap);
  133. return retval;
  134. }
  135. int main(void )
  136. {
  137. //组播接口
  138. if (ONVIF_ClientDiscovery() != 0 )
  139. {
  140. printf("discovery failed!\n");
  141. return -1;
  142. }
  143. return 0;
  144. }
  145. </span>

运行测试结果如下图

可以看到注意信息就是http://172.18.13.127:9000/onvif/device_service这句了!设备的IP地址以及通信端口都有了,第三个没有端口,也就是使用默认的端口80了,海康和大华的貌似都是用80端口
到这里差不多客户端的搜索就完成了,剩下只是把搜索到的设备信息解析出来,然后保存起来!提供给客户端使用了,我在实际开发的过程中是通过调用外层接口传递一个回调函数指针进去,然后匹配信息出来,给客户端!

搜索使用的源码下载地址:onvif客户端搜索

Onvif开发之客户端搜索篇的更多相关文章

  1. Onvif开发之客户端鉴权获取参数篇

    前面一篇已经介绍了客户端如何发些设备,下面这篇简单介绍下在发现设备后,如何通过ONVIF协议来获取设备的相关参数 ONVIF中不管是客户端还是设备端,最先实现的接口都是关于能力的那个接口,在客户端实现 ...

  2. Jsoup开发网站客户端第二篇,图片轮播,ScrollView兼容ListView

    最近一段日子忙的焦头烂额,代码重构,新项目编码,导致jsoup开发网站客户端也没时间继续下去,只能利用晚上时间去研究了.今天实现美食网首页图片轮播效果,网站效果图跟Android客户端实现如图: 从浏 ...

  3. Onvif开发之基础介绍篇

    什么是Onvif协议,谁开启了Onvif时代? ONVIF:原意为 开放型网络视频接口论坛,即 Open Network Video Interface Forum ,是安讯士.博世.索尼等三家公司在 ...

  4. ONVIF客户端搜索设备获取rtsp地址开发笔记(精华篇)

    原文  http://blog.csdn.net/gubenpeiyuan/article/details/25618177   概要: 目前ONVIF协议家族设备已占据数字监控行业半壁江山以上,亲, ...

  5. 【视频开发】ONVIF客户端搜索设备获取rtsp地址开发笔记(精华篇)

    转载地址:http://blog.csdn.net/gubenpeiyuan/article/details/25618177 概要:           目前ONVIF协议家族设备已占据数字监控行业 ...

  6. onvif开发之设备发现功能的实现--转

    忙了一个多月,onvif总算告一段落了.这几个星期忙着其他的项目,也没有好好整理一下onvif的东西.接下来得好好整理一下自己的项目思路和项目经验,同时将自己的一些心得写出来,希望对人有所帮助. 相信 ...

  7. Python开发【第二十一篇】:Web框架之Django【基础】

    Python开发[第二十一篇]:Web框架之Django[基础]   猛击这里:http://www.cnblogs.com/wupeiqi/articles/5237704.html Python之 ...

  8. Python开发【第二十篇】:缓存

    Python开发[第二十篇]:缓存redis&Memcache   点击这里 Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy ...

  9. Struts 2.x仍然明显落后于时代。 Struts 2.x这一类老牌Web MVC开发框架仅能用于开发瘦客户端应用,无法用来开发对于交互体验要求更高的应用。

    后来我在工作中陆续使用过Struts 1.x和Struts 2.x.我曾经把一个开源的基于Struts 1.x的自助式广告联盟应用移植到Spring MVC,还基于Struts 2.x做过网站开发.S ...

随机推荐

  1. nginx 代理https后,应用redirect https变成http --转

    原文地址:http://blog.sina.com.cn/s/blog_56d8ea900101hlhv.html 情况说明nginx配置https,tomcat正常http接受nginx转发.ngi ...

  2. jsp输出金字塔

    <% String str = ""; for(int i = 1; i <= 5; i++){ for(int j = 1; j <= 5-i; j++){ s ...

  3. OnClientClick知识+一个上传的例子

    文件名:<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp ...

  4. 函数响应式编程(FRP)从入门到”放弃”——基础概念篇

    前言 研究ReactiveCocoa一段时间了,是时候总结一下学到的一些知识了. 一.函数响应式编程 说道函数响应式编程,就不得不提到函数式编程,它们俩到底有什么关系呢?今天我们就详细的解析一下他们的 ...

  5. 01背包-第k优解

    The title of this problem is familiar,isn't it?yeah,if you had took part in the "Rookie Cup&quo ...

  6. NodeJS学习笔记 进阶 (6)本地调试远程服务器上的Node代码(ok)

    https://github.com/chyingp/nodejs-learning-guide

  7. centeros安装jdk

    准备工作: java se下载网址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.ht ...

  8. 20180929 北京大学 人工智能实践:Tensorflow笔记03

    更改的程序部分如下: 另: 难?????????????见链接: https://www.bilibili.com/video/av22530538/?p=17 + (完)

  9. 题解 CF915D 【Almost Acyclic Graph】

    这道题我第一次的想法是直接判环的数量,然而事实证明实在是太naive了. 随便画个图都可以卡掉我的解法.(不知道在想什么) 这道题的正解是拓扑排序. 朴素的想法是对所有边都跑一次拓扑,但这样$O(m( ...

  10. 【UVa 1347】Tour

    [Link]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...