gsoap搭建WebService服务

WebService、soap、gsoap基本概念

WebService服务基本概念:就是一个应用程序,它向外界暴露出一个可以通过web进行调用的API,是分布式的服务组件。本质上就是要以标准的形式实现企业内外各个不同服务系统之间的互调和集成。

soap概念:简单对象访问协议,是一种轻量的、简单的、基于 XML 的协议,它被设计成在 WEB 上交换结构化的和固化的信息。

从这里的概念可以看得出来,soap是一个基于xml格式的web交互协议,而webservice是一种使用web方式实现的功能。就好像是网络视频服务器和http的关系,就是这里的webservice服务器和soap的关系。其实从历史上来说,先有的soap这种协议,然后微软用基于这种协议制作了webservice这种服务。

gsoap概念:是一种能够把C/C++语言的接口转换成基于soap协议的webservice服务的工具。

 

gsoap使用方法

步骤1:首先下载gsoap的工具。这里下载了gsoap_2.7.10.解压之后,在里面会发现两个exe可执行文件。soapcpp2.exe和wsdl2h.exe。另外还有两个比较重要的源文件:stdsoap2.h和stdsoap2.cpp。为了使用方便,可以把两个exe可执行文件所在的问价设置到环境变量中。

步骤2:新建一个.h文件用来声明所要暴露给外界的接口。这里以一些运算的接口来作为例子。头文件命名为calculator.h。注意虽然是.h文件,但是千万不能有注释。内容如下:

//gsoap ns service name: calculate
//gsoap ns service style: rpc
//gsoap ns service namespace: http://10.64.57.10/calculate.wsdl
//gsoap ns service location: http://10.64.57.10/calculate.cgi
//gsoap ns schema namespace: urn:calculate

int ns__add(int num1, int num2, int* result );
int ns__sub(int num1, int num2, int* result );
int ns__mult( int num1, int num2, int *result);
int ns__divid( int num1, int num2, int *result);


    步骤3:使用soapcpp2.exe工具来生成相关的源文件。使用方法是soapcpp2 calculator.h

这里没有带选项,那么生成的是最全的源文件,包括客户端的和服务器的以及其它一些文件。当然也可以使用选项来生成需要的文件,可以再命令行下面使用soapcpp2 –help来参看选项。

另外在gsoap的安装目录下面有两个重要的源文件:stdsoap2.h和stdsoap2.cpp。在编译工程的时候要使用。这里罗列一下生成的重要源文件(包括stdsoap2.h和stdsoap2.cpp),它们是:stdsoap2.h、soapStub.h、soapH.h、calculate.nsmap以及stdsoap2.cpp、soapC.cpp、soapClient.cpp soapServer.cpp。

stdsoap2.h和stdsoap2.cpp是gsoap最底层的实现,它们和每次编写的头文件(calculate.h)无关。soapStub.h(存根头文件),包含了stdsoap2.h,里面声明了定义在calculate.h中的接口,包括客户端的和服务器的。还有一个最上层的soapH.h包含了soapStub.h。它是具体实现的声明。和soapC.cpp对应。calculate.nsmap这个文件应该是soap协议相关的一个东西。在编程序时include “calculate.nsmap”就可以了。再来介绍一下源文件,stdsoap2.cpp是和stdsoap2.h对应的,实现最底层的运作,和calculate.h无关;soapC.cpp是和soapH.h对应的,是接口相关的。但是它提供的仅仅是服务器和客户端共有部分的实现。soapClient.cpp也是接口相关的,它里面实现的仅仅是客户端需要的代码。同理soapServer.cpp也是只和服务器相关的。

         好了介绍完了这些源文件,再来梳理一遍。工程中需要的头文件有stdsoap2.h、soapStub.h、soapH.h、calculate.nsmap。但是因为soapStub.h包含了stdsoap2.h;soapH.h包含了soapStub.h,所以工程中只需要包含soapH.h、calculate.nsmap。对于源文件,若是服务器端,需要stdsoap2.cpp、soapC.cpp和soapServer.cpp;客户端则需要stdsoap2.cpp、soapC.cpp和soapClient.cpp;

         为了偷懒,编写了一个脚本来实现调用soapcpp2和拷贝stdsoap2.h、stdsoap2.cpp的功能。名字为AutoGsoap.bat。使用方法是把它放到你定义的calculate.h目录下,然后运行,输入你要操作的头文件名字即可。脚本内容如下:

@echo off

echo "请输入头文件"
set /p headfile=

soapcpp2.exe %headfile%

copy D:\MyApp\ProfessionalApp\gsoap_2.7.10\gsoap-2.7\gsoap\stdsoap2.h  .\ 
copy D:\MyApp\ProfessionalApp\gsoap_2.7.10\gsoap-2.7\gsoap\stdsoap2.cpp  .\
pause

 

         步骤4:建立服务器端的工程。这里以CalculateServer为例 。新建工程后,添加“wsock32.lib”库,gsoap需要用到sock套接字通信。

 

 

然后编写服务器端的主函数,名称为main.cpp,内容如下:

 

#include "soapH.h"
#include "calculate.nsmap"
#include "stdio.h"

int main( int argc, char *argv[])
{
    struct soap *CalculateSoap = soap_new();                                //创建一个soap
    int iSocket_master = soap_bind(CalculateSoap, NULL, 10000, 100);         //绑定到相应的IP地址和端口()NULL指本机,
                                                                            //10000为端口号,最后一个参数不重要。
    if (iSocket_master< 0)                                                  //绑定出错
    {
        soap_print_fault(CalculateSoap, stderr);
        exit(-1);
    }
    printf("SoapBind success,the master socket number is:%d\n",iSocket_master); //绑定成功返回监听套接字
   
    while(1)
    {
        int iSocket_slaver = soap_accept(CalculateSoap);
        if (iSocket_slaver < 0)
        {
            soap_print_fault(CalculateSoap, stderr);
            exit(-2);
        }
        printf("Get a new connection,the slaver socket number is:%d\n",iSocket_slaver); //绑定成功返回监听套接字
        soap_serve(CalculateSoap);
        soap_end(CalculateSoap);
    }
    soap_done(CalculateSoap);
    free(CalculateSoap);

    return 0;
}

/*加法的具体实现*/
int ns__add(struct soap *soap, int num1, int num2, int* result )  
{
    if (NULL == result)
    {
        printf("Error:The third argument should not be NULL!\n");
        return SOAP_ERR;
    }
    else
    {
        (*result) = num1 + num2;
        return SOAP_OK;
    }
    return SOAP_OK;
}

/*减法的具体实现*/
int ns__sub(struct soap *soap,int num1, int num2, int* result )
{
    if (NULL == result)
    {
        printf("Error:The third argument should not be NULL!\n");
        return SOAP_ERR;
    }
    else
    {
        (*result) = num1 - num2;
        return SOAP_OK;
    }
    return SOAP_OK;
}

/*乘法的具体实现*/
int ns__mult(struct soap *soap, int num1, int num2, int *result)
{
    if (NULL == result)
    {
        printf("Error:The third argument should not be NULL!\n");
        return SOAP_ERR;
    }
    else
    {
        (*result) = num1 * num2;
        return SOAP_OK;
    }
    return SOAP_OK;
}

/*除法的具体实现*/
int ns__divid(struct soap *soap, int num1, int num2, int *result)
{
    if (NULL == result || 0 == num2)
    {
        printf("Error:The second argument is 0 or The third argument is NULL!\n");
        return SOAP_ERR;
    }
    else
    {
        (*result) = num1 / num2;
        return SOAP_OK;
    }
    return SOAP_OK;
}

 

编译,运行服务器端程序,从IE浏览器访问10.64.57.10:10000 (该服务器运行的本机IP地址为10.64.57.10)如能看到如下信息,说明服务器运行正常:

 

         步骤5:新建客户端程序进行验证。新建工程如下,同样要包含wsock32.lib。

 


/*客户端主程序*/
#include "soapH.h"
#include "calculate.nsmap"
#include "stdio.h"


int main( int argc, char *argv[])
{
    printf("The Client is runing...\n");
    int num1 = 110;
    int num2 = 11;
    int result = 0;

    struct soap *CalculateSoap = soap_new();
    //soap_init(CalculateSoap);
    char * server_addr = "http://10.64.57.10:10000";

    int iRet = soap_call_ns__add(CalculateSoap,server_addr,"",num1,num2,&result);
    if ( iRet == SOAP_ERR)
    {
        printf("Error while calling the soap_call_ns__add");
    }
    else
    {
        printf("Calling the soap_call_ns__add success。\n");
        printf("%d + %d = %d\n",num1,num2,result);
    }

    iRet = soap_call_ns__sub(CalculateSoap,server_addr,"",num1,num2,&result);
    if ( iRet == SOAP_ERR)
    {
        printf("Error while calling the soap_call_ns__sub");
    }
    else
    {
        printf("Calling the soap_call_ns__sub success。\n");
        printf("%d - %d = %d\n",num1,num2,result);
    }

    iRet = soap_call_ns__mult(CalculateSoap,server_addr,"",num1,num2,&result);
    if ( iRet == SOAP_ERR)
    {
        printf("Error while calling the soap_call_ns__mult");
    }
    else
    {
        printf("Calling the soap_call_ns__mult success。\n");
        printf("%d * %d = %d\n",num1,num2,result);
    }

    iRet = soap_call_ns__divid(CalculateSoap,server_addr,"",num1,num2,&result);
    if ( iRet == SOAP_ERR)
    {
        printf("Error while calling the soap_call_ns__divid");
    }
    else
    {
        printf("Calling the soap_call_ns__divid success。\n");
        printf("%d / %d = %d\n",num1,num2,result);
    }
    soap_end(CalculateSoap);
    soap_done(CalculateSoap);
    free(CalculateSoap);

    return 0;
}


 

 

 

 

开启服务器之后,运行客户端程序,打印信息如下:

 

此时服务器端也检测到了四个连接:

 

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
gSOAP是一个C/C++的SOAP (Simple Object Access Protocol)开发工具箱,可以用来实现Web Services以及SOAP消息的编解码。通过使用gSOAP,可以方便快捷地实现ONVIF服务。 以下是实现ONVIF服务的步骤: 1. 下载和安装gSOAP工具箱。 2. 生成服务端代码。使用gSOAP提供的命令行工具wsdl2h,将ONVIF的WSDL文件转换为gSOAP的头文件。例如: ``` wsdl2h -o onvif.h http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl ``` 3. 生成客户端代码。使用gSOAP提供的命令行工具soapcpp2,将ONVIF的WSDL文件转换为gSOAP的客户端代码。例如: ``` soapcpp2 -i -C onvif.h ``` 4. 实现服务端程序。在服务端程序中,需要实现ONVIF的各个接口函数,并使用gSOAP提供的API进行SOAP消息的编解码和发送。例如: ```c++ #include "soapH.h" #include "onvif.nsmap" int main(int argc, char** argv) { struct soap soap; soap_init(&soap); // 实现ONVIF的各个接口函数 soap_serve(&soap); soap_destroy(&soap); soap_end(&soap); soap_done(&soap); return 0; } ``` 5. 实现客户端程序。在客户端程序中,需要使用gSOAP提供的API进行SOAP消息的编解码和发送,并调用ONVIF的各个接口函数。例如: ```c++ #include "soapH.h" #include "onvif.nsmap" int main(int argc, char** argv) { struct soap soap; soap_init(&soap); // 调用ONVIF的各个接口函数 soap_destroy(&soap); soap_end(&soap); soap_done(&soap); return 0; } ``` 6. 编译和运行程序。使用gSOAP提供的命令行工具soapcpp2,将生成的客户端和服务端代码编译成可执行程序。例如: ``` soapcpp2 -i -C onvif.h gcc -o onvif_server onvif_server.cpp onvif_serverC.cpp soapC.cpp stdsoap2.cpp gcc -o onvif_client onvif_client.cpp onvif_clientC.cpp soapC.cpp stdsoap2.cpp ``` 7. 测试程序。运行服务端程序,并使用客户端程序调用ONVIF的各个接口函数进行测试。例如: ``` ./onvif_server & ./onvif_client ``` 以上就是使用gSOAP实现ONVIF服务的基本步骤。需要注意的是,gSOAP提供了丰富的API和工具,可以根据具体的需求进行定制和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值