ONVIF协议网络摄像机

2017-08-01  本文已影响1309人  bobociel
logo.PNG

来源:CSDN

一 使用IPC摄像头

  1. IPC摄像头接入有线网络,PC也接入有线网络,保证IPC和PC在同一局域网。(保证ip的前三部分相同。)
  2. 下载IP Camera获得ONVIF Device Test Tool 来搜索摄像头信息。
  3. 在PC浏览器中输入IPC的ip地址和端口,输入账户名和密码进入网络摄像机控制台。 可以设置IPC无线连接信息,IPC录制视频信息等。

二 理解Web Service和ONVIF

Web Service是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web Service能与其他兼容的组件进行互操作

ONVIF(Open Network Video Interface Forum,开放型网络视频接口论坛)ONVIF规范描述了网络视频的模型、接口、数据类型以及数据交互的模式。并复用了一些现有的标准,如WS系列标准等。ONVIF规范的目标是实现一个网络视频框架协议,使不同厂商所生产的网络视频产品(包括摄录前端、录像设备等)完全互通。  
ONVIF规范中设备管理和控制部分所定义的接口均以Web Services 的形式提供。

ONVIF规范的内容结构:
[图片上传失败...(image-c8512e-1534605862114)]

ONVIF规范的网络层次结构:


ONVIF接口被划分为不同模块,包括:设备发现、设备管理、设备输入输出服务、图像配置、媒体配置、实时流媒体、接收端配置、显示服务、事件处理、PTZ控制等。

SOAP介绍

三 使用gSOAP生成Web Service框架

ONVIF标准是使用SOAP方式实现的Web Services,上一章介绍了Web Services,涉及到很多概念,包括SOAP,HTML,XML,RPC等很多东西。开发时我们可以使用gSOAP自动生成大部分代码框架,而不需要自己造轮子。
这样的工具有:
1, gSOAP工具,适用于C/C++语言开发。
2, Apache CXF工具,适用于JAVA语言开发。

1, gSOAP简介

gSOAP官网:http://www.cs.fsu.edu/~engelen/soap.html
gSOAP源码下载地址:http://sourceforge.net/projects/gsoap2

gSOAP编译工具提供了一个SOAP关于C/C++语言的实现,从而让C/C++语言开发Web Service服务器或客户端程序的工作变得轻松很多。

gSOAP会生成哪些框架代码,下图中绿色的部分就是自动生成的代码。
[图片上传失败...(image-5f872a-1534605862114)]

2, gSOAP工具转换原理

gSOAP工具根据WSDL文档,自动生成C/C++语言的客户端/服务器框架代码。这其中有两个重要的工具,wsdl2h和soapcpp2。wsdl2h工具根据WSDL文档生成C/C++头文件,而soapcpp2工具是根据该头文件生成C/C++的框架代码。

gSOAP工具可以在Windows、Linux和MaxOSX操作系统下运行,gSOAP工具包中自带有Windows和MaxOSX操作系统的wsdl2h和soapcpp2可执行文件,而Linux操作系统得自己编译。

[图片上传失败...(image-8797d8-1534605862114)]

如何使用gSOAP,在gSOAP官网,或者在工具包gsoap\doc\soapdoc2.pdf文档中都有很详细的说明,大家可以参考。下面我们通过【国内手机号码归属地查询】的例子,来演示如何使用gSOAP工具。

3, 手机号码归属地查询

国内手机号码归属地查询 免费WEB服务:
WEB服务地址: http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx
WSDL: http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl

(1) 下载gSOAP工具。
(2) 创建MobileCode,从gSOAP工具中拷贝如下文件到文件夹MobileCode文件夹

gsoap_2.8.45\gsoap-2.8\gsoap\bin\win32\soapcpp2.exe
gsoap_2.8.45\gsoap-2.8\gsoap\bin\win32\wsdl2h.exe
gsoap_2.8.45\gsoap-2.8\gsoap\stdsoap2.c
gsoap_2.8.45\gsoap-2.8\gsoap\stdsoap2.h
gsoap_2.8.45\gsoap-2.8\gsoap\typemap.dat
gsoap_2.8.45\gsoap-2.8\gsoap\import\
gsoap_2.8.45\gsoap-2.8\gsoap\custom\

(3) 启动cmd.exe,进入MobileCode目录。
(4) 使用wsdl2h工具,根据WSDL产生头文件,在cmd中执行以下命令:

wsdl2h.exe -o mobilecode.h -c -s -t typemap.dat http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl

其中-c为产生纯c代码,默认生成c++代码;-s为不使用STL库,-t为typemap.dat的标识。详情可通过wsdl2h.exe -help查看帮助。这里的WSDL文件,可以在wsdl2h命令中在线下载,也可以先下载到本地,然后引用本地WSDL文件。
(5) 使用soapcpp2工具,根据头文件产生框架代码,在cmd中命令如下:

soapcpp2.exe -2 -C -c -x -Iimport -Icustom mobilecode.h

-2为生成SOAP 1.2版本代码, -C为仅生成客户端代码,-c为生成C语言代码。详情可使用soapcpp2.exe -help查看帮助。
(6) 自动生成的源码文件如下图所示
[图片上传失败...(image-6717eb-1534605862114)]

其中custom, import, wsdl2h.exe, soapcpp2.exe, typemap.dat, mobilecode.h, soapClientLib.c这些文件已经没用了,可以删掉,剩下的文件有:
[图片上传失败...(image-143fac-1534605862114)]
在soapStub.h文件中,列出了[国内手机号码归属地查询] WEB服务的所有接口(Client-Side Call Stub Functions), 我们的应用程序通过调用这些接口就成了,值域SOAP协议整个过程怎么实现的,都在soapC.c和soapClient.c中,有兴趣的可以去研究。至少懂得调用一下接口:
[图片上传失败...(image-477684-1534605862114)]

(7) 接下来,写个mian.c,通过soap_call_ns1_getMobileCodeInfo接口来查询国内手机号码归属地信息,并将其打印出来,源码如下所示:

#include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "soapStub.h"
    #include "MobileCodeWSSoap.nsmap"

    void getMobileCodeInfo(char *mobileCode)
    {
        struct soap *soap = NULL;
        const char  *endpoint = "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx";
        struct _ns1__getMobileCodeInfo          req;
        struct _ns1__getMobileCodeInfoResponse  resp;

        soap = soap_new();                                                          // allocate and initalize a context

        soap_set_mode(soap, SOAP_C_UTFSTRING);                                      // support multibyte string(for Chinese)

        memset(&req, 0x00, sizeof(req));
        req.mobileCode = mobileCode;
        req.userID     = NULL;

        if(SOAP_OK == soap_call___ns1__getMobileCodeInfo(soap, endpoint, NULL, &req, &resp)) {
            if (NULL != resp.getMobileCodeInfoResult) {
                printf("%s\n", resp.getMobileCodeInfoResult);
            }
        }

        soap_destroy(soap);                                                         // delete deserialized objects
        soap_end(soap);                                                             // delete allocated data
        soap_free(soap);                                                            // free the soap struct context data
    }

    int main(int argc, char **argv)
    {
        if (argc < 2) {
            return 0;
        }
        getMobileCodeInfo(argv[1]);

        return 0;
    }

执行代码会出现乱码,这是由于WEB服务应答的归属地信息中包含有UTF-8格式的中文导致的。SOAP协议采用HTTP传输协议+XML数据格式,规定XML字符编码格式必须是UTF-8。为了解决这个问题:
① 在源码汇中加入soap_set_mode(soap,SOAP_C_UTFSTRING)语句,告知gSOAP底层代码,我们上层传入的字符编码格式是UTF-8,内部就不参与转码的过程,WEB服务器应答的UTF-8字符也都直接传给上层,此时我们的main.c代码收到的应答也是UTF-8格式的数据。
② md.exe环境默认的环境是「简体中文GBK」,通过chcp命令就能查到,「活动代码页936」代表的就是「简体中文GBK」,在这种环境下打印UTF-8中文字符当然会乱码,使用命令chcp 65001将控制台的字符集改为UTF-8,「活动代码页65001」代表的就是UTF-8,如此就不会乱码了。

乱码问题,这个例子还算是简单的,仅仅是服务器应答的时候带有UTF-8格式的中文字符,从控制台输入的字符(手机号码)是纯数字的,没有涉及到UTF-8编码问题。如果输入也带有中文,那情况会更复杂,有关这方面的详细情况,可参考我博客中此前写的一篇文章「浅谈C/C++编程中的字符编码转换」。

总结

对本文做个总结:
开发基于SOAP方式的Web Services,不需要自己实现代码框架,有诸如gSOAP、Apache CXF这样的工具会帮我们实现。

[图片上传失败...(image-2e233f-1534605862114)]

以「国内手机号码归属地查询」为例,重点介绍了gSOAP工具转换原理,及其使用方法。

还遇到了SOAP协议中UTF-8中文字符打印到控制台会乱码的问题,并给出了解决方法。

上一篇下一篇

猜你喜欢

热点阅读