C++ 开发SOAP服务端和SOAP客户端
作者:flyfish 2012-5-12
目的:利用gSOAP自带的Calc例子 仿写一个 网络中使用计算器
客户端通过http发送xml格式的数据请求,服务端计算完之后,将结果以xml格式返回给客户端。
编写之后 我们的服务端可独立使用。像在安装了IIS或者用Apache配置的Web服务器。
gSoap版本 2.8.8
编译环境为 winXP+VC6
soapcpp2.exe和wsdl2h.exe这两个文件的目录是
gsoap_2.8.8\gsoap-2.8\gsoap\bin\win32路径
生成服务端文件命令 soapcpp2.exe -S -i -T calc.h文件的路径
生成客户端文件命令 soapcpp2.exe -C -i calc.h文件的路径
-S的含义是生成服务端代码
-C 的含义是生成客户端代码
-T 生成一个测试例子,我们可以仿照这个例子编写自己的程序
-i从SOAP结构生成服务代理和继承的对象
服务端编写
用vc新建一个win32控制台的工程名字叫ServerCal
添加到工程中的文件包括
soapC.cpp
soapcalcService.h
soapcalcService.cpp
soapH.h
soapStub.h
calc.nsmap
stdsoap2.h
stdsoap2.cpp
stdsoap2.h和 stdsoap2.cpp这两个文件存在gsoap_2.8.8\gsoap-2.8\gsoap目录下面
main函数存所在的文件是ServerCalc.cpp
#include "soapcalcService.h"
#include "calc.nsmap"
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;
}
int calcService::add(doublea, double b, double*result)
{ *result = a + b;
return SOAP_OK;
}
int calcService::sub(doublea, double b, double*result)
{ *result = a - b;
return SOAP_OK;
}
实现乘法,除法等的其他接口见源码
主函数代码比较简单,因为calcService 进行了一些封装
生成编译看下,运行下。要在控制台运行。使用cmd命令
exe程序的路径 端口号
例如 c:\ServerCalc.exe 8080
服务端运行起来之后,在浏览器输入http://localhost:8080/
如果没有看到类似下面的xml格式的文件,说明服务器出现错误
<?xmlversion="1.0" encoding="UTF-8" ?>
-<SOAP-ENV:Envelopexmlns: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>HTTPGET method not implemented</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
客户端的编写
新建一个控制台程序 ClientCalc
需要添加到工程的文件包括
calc.nsmap
soapC.cpp
soapcalcProxy.cpp
soapcalcProxy.h
socpClient.cpp
soapH.h
soapStub.h
stdsoap2.h
stdsoap2.cpp
ClientCalc.cpp为main函数所在的文件,客户端代码如下
#include "soapcalcProxy.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;
}
生成客户端exe,命令行执行
C:\Documents andSettings\Administrator>C:\work\ClientCalc\Debug\ClientCalc.exe a 1 2
让服务端计算1+2等于多少
如果出现如下错误,通常错误的原因是客户端的端口号与服务端的端口号不匹配
SOAP 1.1 fault:SOAP-ENV:Client[no subcode]
由于目标机器积极拒绝,无法连接。
Detail: connectfailed in tcp_connect()
源码下载地址:http://download.csdn.net/detail/flyfish1986/4299760
以上代码在winxp和vc6下编译通过