0002.onvif规范的实现:使用gSOAP创建SOAP调用实例_第1页
0002.onvif规范的实现:使用gSOAP创建SOAP调用实例_第2页
0002.onvif规范的实现:使用gSOAP创建SOAP调用实例_第3页
0002.onvif规范的实现:使用gSOAP创建SOAP调用实例_第4页
0002.onvif规范的实现:使用gSOAP创建SOAP调用实例_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

预备知识ONVIF规范中设备管理和控制部分所定义的接口均以Web Services的形式提供。ONVIF规范涵盖了完全的XML及WSDL的定义。每一个支持ONVIF规范的终端设备均须提供与功能相应的Web Service。服务端与客户端的数据交互采用SOAP协议。【来自/ghostyu】ONVIF中的其他部分比如音视频流则通过RTP/RTSP进行 。那么WebServices、SOAP、WSDL、gSOAP又都是什么?假如我们需要开发一个linux上的app,这个app需要与远端的Web服务有一个交互,比如获取一个运算结果、或者是天气等,那么我们就需要使用WebServices。Web Services可以概述为:Web Services 可以将应用程序转换为网络应用程序。通过使用 Web Services,应用程序可以向全世界发布信息,或提供某项功能。Web Services 可以被其他应用程序使用。通过 Web Services,会计部门的 Win 服务器可以与 IT 供应商的 UNIX 服务器相连接。基本的 Web Services 平台是 XML+HTTP。Web services 使用 XML 来编解码数据,并使用 SOAP 来传输数据。SOAP又是什么?SOAP 是基于 XML 的简易协议,可使应用程序在 HTTP 之上进行信息交换。或者更简单地说:SOAP 是用于访问网络服务的协议。对于应用程序开发来说,使程序之间进行因特网通信是很重要的。目前的应用程序通过使用远程过程调用(RPC)在诸如 DCOM 与 CORBA 等对象之间进行通信,但是 HTTP 不是为此设计的。RPC 会产生兼容性以及安全问题;防火墙和代理服务器通常会阻止此类流量。通过 HTTP 在应用程序间通信是更好的方法,因为 HTTP 得到了所有的因特网浏览器及服务器的支持。SOAP 就是被创造出来完成这个任务的。SOAP 提供了一种标准的方法,使得运行在不同的操作系统并使用不同的技术和编程语言的应用程序可以互相进行通信。如何实现SOAP?我们要知道SOAP协议是基于XML的,那么如何能够将他们嵌入到C/C+的应用程序里使用?gSOAP编译工具就提供了一个SOAP/XML 关于C/C+ 语言的实现,从而让C/C+语言开发web服务或客户端程序的工作变得轻松了很多。将与开发无关的SOAP协议的实现细节相关的内容对开发人员隐藏起来。因为SOAP提供的是一种标准化的方法,gSOAP的编译器能够自动的将用户定义的本地化的C或C+数据类型转变为符合XML语法的数据结构,这样,只用一组简单的API就将用户从SOAP细节实现工作中解脱了出来,可以专注与应用程序逻辑的实现工作了。并且可以跨越多个操作系统、语言环境以及在防火墙后的不同组织。更直白的说,使用gSOAP可以产生用于开发Web Services的SOAP通信协议方面的代码框架,开发人员只需要实现server的被调用的函数,然后在client端就可以像调用本地函数一样调用在远端的函数。gSOAP包含两个工具wsdl2h和soapcpp2,用来产生代码框架。开发Web服务程序,需使用gSOAP生成服务器端和客户端代码框架(通常情况下之需要实现server端或者实现client,因为另一端通常是别人做好的,比如ipnc中的onvif,实现的server端)。我们有两种做法:编写WSDL,使用wsdl2h生成头文件,再soapcpp2生成框架代码;编写头文件,使用soapcpp2生成框架代码;这两种方式,结果是一样的,最终都有产生头文件,并生成代码。不同在于,在项目的开发中需要维护的文件不同,前者是需要维护WSDL文件,后者维护头文件。SOAP调用示例下面就使用第二种方法来实现一个简单的通信实例:在远端实现两数相加,然后返回运算结果。1、下载gSOAP我使用的版本时2.8.8,/file/id_48923272389088693.htmgSOAP-2.8软件包不需要安装,直接解压,在gsoap-2.8gsoapbin目录下是上面提到的两个命令行工具,包含win32、linux、maxOS等三种版本,在使用soapcpp2生产代码框架时一般需要gsoap-2.8gsoapimport目录下和gsoap-2.8gsoapcustom的 文件。在命令行中使用-I包含进来即可。2、编写头文件:add.h在这里我们不需要wsdl的文件,可以直接从.h文件来生成代码。我们定义一个函数声明文件,用来定义接口函数,名称为add.hcpp view plaincopyprint?1. /gsoapoptcw2. /gsoapns2schemanamespace:urn:add3. /gsoapns2schemaform:unqualified4. /gsoapns2servicename:add5. /gsoapns2servicetype:addPortType6. /gsoapns2serviceport:/engelen/addserver.cgi7. /gsoapns2servicenamespace:urn:add8. /gsoapns2servicetransport:/soap/http9. /gsoapns2servicemethod-style:addrpc10. /gsoapns2servicemethod-encoding:add/soap/encoding/11. /gsoapns2servicemethod-action:add12. intns2_add(intnum1,intnum2,int*sum);/gsoapopt cw/gsoap ns2 schema namespace: urn:add/gsoap ns2 schema form: unqualified/gsoap ns2 service name: add/gsoap ns2 service type: addPortType/gsoap ns2 service port:/engelen/addserver.cgi/gsoap ns2 service namespace: urn:add/gsoap ns2 service transport: /soap/http/gsoap ns2 service method-style: add rpc/gsoap ns2 service method-encoding: add /soap/encoding/gsoap ns2 service method-action: add int ns2_add( int num1, int num2, int* sum );3、产生代码框架 我们执行一下命令,自动生成一些远程调用需要的文件。(先将他们加如到系统环境变量中)soapcpp2 -c add.h-c是产生纯C代码,如果提示找不到typemap.dat,将gsoap-2.8gsoap下的typemap.dat复制到当前目录就可以了。通过上列命令我们会得到如下文件:先大概记住他们的名字,将来会提到他们。4、添加服务端代码,创建文件:addserver.ccpp view plaincopyprint?1. #includesoapH.h2. #includeadd.nsmap3. 4. intmain(intargc,char*argv)5. 6. intm,s;7. structsoapadd_soap;8. soap_init(&add_soap);9. soap_set_namespaces(&add_soap,namespaces);10. 11. if(argc2)12. printf(usage:%sn,argv0);13. exit(1);14. else15. m=soap_bind(&add_soap,NULL,atoi(argv1),100);16. if(m0)17. soap_print_fault(&add_soap,stderr);18. exit(-1);19. 20. fprintf(stderr,Socketconnectionsuccessful:mastersocket=%dn,m);21. for(;)22. s=soap_accept(&add_soap);23. if(s0)24. soap_print_fault(&add_soap,stderr);25. exit(-1);26. 27. fprintf(stderr,Socketconnectionsuccessful:slavesocket=%dn,s);28. soap_serve(&add_soap);29. soap_end(&add_soap);30. 31. 32. return0;33. 34. #if135. intns2_add(structsoap*add_soap,intnum1,intnum2,int*sum)36. 37. *sum=num1+num2;38. return0;39. 40. #endif#include soapH.h#include add.nsmapint main(int argc, char *argv) int m, s; struct soap add_soap; soap_init(&add_soap); soap_set_namespaces(&add_soap, namespaces); if (argc 2) printf(usage: %s n, argv0); exit(1); else m = soap_bind(&add_soap, NULL, atoi(argv1), 100); if (m 0) soap_print_fault(&add_soap, stderr); exit(-1); fprintf(stderr, Socket connection successful: master socket = %dn, m); for (;) s = soap_accept(&add_soap); if (s 0) soap_print_fault(&add_soap, stderr); exit(-1); fprintf(stderr, Socket connection successful: slave socket = %dn, s); soap_serve(&add_soap); soap_end(&add_soap); return 0;#if 1int ns2_add(struct soap *add_soap, int num1, int num2, int *sum) *sum = num1 + num2; return 0;#endif5、添加客户端代码,创建文件:addclient.c cpp view plaincopyprint?1. #includesoapStub.h2. #includeadd.nsmap3. 4. intadd(constchar*server,intnum1,intnum2,int*sum)5. 6. structsoapadd_soap;7. intresult=0;8. soap_init(&add_soap);9. soap_set_namespaces(&add_soap,namespaces);10. soap_call_ns2_add(&add_soap,server,NULL,num1,num2,sum);11. printf(serveris%s,num1is%d,num2is%d/n,server,num1,num2);12. 13. if(add_soap.error)14. printf(soaperror:%d,%s,%sn,add_soap.error,*soap_faultcode(&add_soap),*soap_faultstring(&add_soap);15. result=add_soap.error;16. 17. soap_end(&add_soap);18. soap_done(&add_soap);19. returnresult;20. #include soapStub.h#include add.nsmapint add(const char *server, int num1, int num2, int *sum) struct soap add_soap; int result = 0; soap_init(&add_soap); soap_set_namespaces(&add_soap, namespaces); soap_call_ns2_add(&add_soap, server, NULL, num1, num2, sum); printf(server is %s, num1 is %d, num2 is %d/n, server, num1, num2); if (add_soap.error) printf(soap error: %d, %s, %sn, add_soap.error, *soap_faultcode(&add_soap), *soap_faultstring(&add_soap); result = add_soap.error; soap_end(&add_soap); soap_done(&add_soap); return result;6、写客户端测试代码,创建文件:addtest.c cpp view plaincopyprint?1. #include2. #include3. #include4. 5. intadd(constchar*server,intnum1,intnum2,int*sum);6. intmain(intargc,char*argv)7. 8. intresult=-1;9. charserver128=0;10. intnum1;11. intnum2;12. intsum;13. 14. if(argc4)15. printf(usage:%snum1num2n,argv0);16. exit(1);17. 18. 19. strcpy(server,argv1);20. num1=atoi(argv2);21. num2=atoi(argv3);22. result=add(server,num1,num2,&sum);23. 24. if(result!=0)25. printf(soaperror,errcode=%dn,result);26. else27. printf(%d+%d=%dn,num1,num2,sum);28. 29. return0;30. #include #include #include int add(const char *server, int num1, int num2, int *sum);int main(int argc, char *argv) int result = -1; char server128 = 0; int num1; int num2; int sum; if (argc 4) printf(usage: %s num1 num2 n, argv0); exit(1); strcpy(server,argv1); num1 = atoi(argv2); num2 = atoi(argv3); result = add(server, num1, num2,&sum); if (result != 0) printf(soap error, errcode=%dn, result); else printf(%d + %d = %dn, num1, num2, sum); return 0;7、编写Makefile,编译前,先将gsoap-2.8gsoap目录下的stdsoap2.c和stdsoap2.h复制到当前目录下,它提供了对SOAP协议的简单调用。 cpp view plaincopyprint?1. GSOAP_ROOT=/root/onvif/gsoap-2.8/gsoap2. CC=gcc-g-DWITH_NONAMESPACES3. INCLUDE=-I$(GSOAP_ROOT)4. SERVER_OBJS=soapC.ostdsoap2.osoapServer.oaddserver.o5. CLIENT_OBJS=soapC.ostdsoap2.osoapClient.oaddclient.oaddtest.o6. 7. all:server8. server:$(SERVER_OBJS)9. $(CC)$(INCLUDE)-oaddserver$(SERVER_OBJS)10. 11. client:$(CLIENT_OBJS)12. $(CC)$(INCLUDE)-oaddtest$(CLIENT_OBJS)13. 14. clean:15. rm-f*.oaddtestGSOAP_ROOT = /root/onvif/gsoap-2.8/gsoapCC = gcc -g -DWITH_NONAMESPACESINCLUDE = -I$(GSOAP_ROOT)SERVER_OBJS = soapC.o stdsoap2.o soapServer.o addserver.o CLIENT_OBJS = soapC.o stdsoap2.o soapClient.o addclient.o addtest.oall: serverserver: $(SERVER_OBJS) $(CC) $(INCLUDE) -o addserver $(SERVER_OBJS) client: $(CLIENT_OBJS) $(CC) $(INCLUDE) -o addtest $(CLIENT_OBJS)clean:rm -f *.o addtest8、编译服务端make server,编译客户端make client 得到addserver和addtest 9、测试一个最简单的soap调用的例子完成了。实例分析服务端代码下面我们来分析上面的例子,刚才我们只是创建一个add.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论