C++ Soap编程入门

工具包地址:http://gsoap2.sourceforge.net/

原理:请自行了解wsdl、webService、soap

soap简单介绍http://www.runoob.com/soap/soap-tutorial.html

wsdl简单介绍http://www.runoob.com/wsdl/wsdl-tutorial.html

webService简单介绍http://www.runoob.com/webservices/webservices-tutorial.html

毕竟是简单介绍,了解基本信息即可

我下载的gsoap版本是2.8,所以exe工具目录是gsoap-2.8\gsoap\bin\win32,win32目录中是可执行文件包括soapcpp2.exe和wsdl2h.exe,

wsdl2h用作wsdl和.h文件的转换。

soapcpp2用头文件生成客户端/服务端等开发需要的h和cpp文件,也可以生成wsdl文件

此处直接使用gsoap2.8中自带的sample演示。目录为gsoap-2.8\gsoap\samples\calc。gsoap-2.8\gsoap\samples中有很多实例,网上多疑calc为例,本文也是。

(cd   到gsoapcpp2和wsdl2h所在目录)

服务端:

1.生成服务端必要文件

soapcpp2.exe -S -i  ..\..\samples\calc\calc.h

-S表示生成服务端文件

-i表示SOAP结构生成服务代理和继承的对象

这里win32目录下会生成很多xml文件、cpp文件、h文件,还有wsdl文件、nsmap文件、xsd文件,可以通过-d参数指定路径,以免管理混乱,还可以拒绝xml文件的生成

请先手动在win32目录下创建calcServer目录

soapcpp2.exe -S -i -x ..\..\samples\calc\calc.h -d .\calcServer

-x表示不生成xml文件,结果如下


2.新建工程

不赘述

main.cpp代码如下

#include "soapcalcService.h"
#include "calc.nsmap"
#include <math.h>


int main(int argc, char **argv)
{
calcService calc;

if (argc < 2)
{
calc.serve();      /* serve as CGI application */
}
else
{
int port = atoi(argv[1]);

if (!port)
{
fprintf(stderr, "Usage:calcserver++ <port>\n");

exit(0);
}


/* run iterative server on port untilfatal error */


if (calc.run(port))
{
calc.soap_stream_fault(std::cerr);


exit(-1);
}
}

return 0;
}

/** Auto-test server operation ns__add */
int calcService::add(double a, double b, double *result)
{ /* Echo request-response parameter */
*result = a + b;
return SOAP_OK;
}

/** Auto-test server operation ns__sub */
int calcService::sub(double a, double b, double *result)
{ /* Echo request-response parameter */
*result = a - b;
return SOAP_OK;
}

/** Auto-test server operation ns__mul */
int calcService::mul(double a, double b, double *result)
{ /* Echo request-response parameter */
*result = a * b;
return SOAP_OK;
}

/** Auto-test server operation ns__div */
int calcService::div(double a, double b, double *result)
{ /* Echo request-response parameter */
*result = a / b;
return SOAP_OK;
}

/** Auto-test server operation ns__pow */
int calcService::pow(double a, double b, double *result)
{ /* Echo request-response parameter */
*result = ::pow(a, b);
return SOAP_OK;
}

需要自己实现h文件中定义的4个接口。可以理解为:h文件里面声明了,总得自己实现吧。可以参考gsoap-2.8\gsoap\samples\calc中calcserver.cpp的实现。只有头文件和参考的cpp文件的情况下,自己不实现,没人帮你实现。

除了main.cpp文件以外,还需要将生成的

calc.nsmap

soapC.cpp

soapcalcService.cpp

soapcalcService.h

soapH.h

soapStub.h

和gsoap目录下的

stdsoap2.cpp

stdsoap2.h

复制到工程目录下

3.直接编译,测试

编译后,用命令行窗口执行testSoapCalc 8080

然后用浏览器打开http://localhost:8080

看到的是

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:calc">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode> SOAP-ENV:Client </faultcode>
<faultstring> HTTP GET method not implemented </faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

因为只是打开端口,并没有通信,所以只能看到这些,编译执行客户端程序就能看到效果了

客户端:

1.生成客户端必要文件

soapcpp2.exe -C -i -x ..\..\samples\calc\calc.h -d .\calcClient\

请手动在win32目录下创建calcClient目录 

-C表示生成客户端代码


2.新建工程


需要复制的是生成的

calc.nsmap

soapC.cpp

soapcalcProxy.cpp

soapcalcProxy.h

soapH.h

soapStub.h

以及soap目录下的

stdsoap2.cpp

stdsoap2.h

一定要记得stdsoap2.cpp和stdsoap2.h,

一定要记得stdsoap2.cpp和stdsoap2.h,

一定要记得stdsoap2.cpp和stdsoap2.h,

重要的事情说三遍

main.cpp代码如下

#include "soapcalcProxy.h"
#include "calc.h"
#include "calc.nsmap"


const char server[] = "http://localhost:8080";


int main(int argc, char **argv)
{
if (argc < 4)

{

    fprintf(stderr, "Usage:[add|sub|mul|div|pow] num num\n");

    exit(0);
}

double a, b, result;
a = strtod(argv[2], NULL);
b = strtod(argv[3], NULL);

calcProxy calc;
calc.soap_endpoint = server;


switch (*argv[1])
{
case 'a':
calc.add(a, b, &result);
break;
case 's':
calc.sub(a,b, &result);
break;
case 'm':
calc.mul(a,b, &result);
break;
case 'd':
calc.div(a,b, &result);
break;
case 'p':
calc.pow(a,b, &result);
break;
default:
fprintf(stderr,"Unknown command\n");

exit(0);
}


if (calc.error)
calc.soap_stream_fault(std::cerr);
else

printf("result = %g\n", result);


return 0;

}

其中const char server[] = "http://localhost:8080";指定端口号,端口号可改以服务端设置的端口号为准

3.编译执行

服务端程序要运行起来才能执行客户端程序,虽然都在同一台电脑里面

testSoapCalcClient.exe a 1 2

运算1和2的加法

运算完后服务端不会退出,但是客户端会退出,可继续执行命令


soapCalcProxy.cpp和soapClient.cpp有冲突
-i生成soapCalcProxy.cpp,不会生成soapClient.cpp文件
不要-i则生成soapClient.cpp不生成soapCalcProxy.cpp文件
没有soapClient.cpp也没关系,只要有编译出来的nsmap文件、cpp文件、h文件和soap目录下的stdsoap2.cpp、stdsoap2.h文件就够了

猜你喜欢

转载自blog.csdn.net/youyudexiaowangzi/article/details/79972597