功能:
实现一个简单的a+b程序,在服务器端写一个程序,里面包含了a+b的函数
然后通过客户端代码向其发送两个数字,在服务器运算得到结果返回给客户端显示出来
1、gSOAP官网下载
http://sourceforge.net/projects/gsoap2/files/
2、新建一个目录gsoaptest,
解压gsoap_2.8.18.zip,
将gsoap-2.8\gsoap\bin\win32下的soapcpp2.exe放到gsoaptest里面
3、在gsoaptest目录建立一个add.h的头文件
输入下面代码
//gsoap ns service name: add
//gsoap ns service namespace: http://localhost/add.wsdl
//gsoap ns service location: http://localhost
//gsoap ns service executable: add.cgi
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:add
int ns__add( int num1, int num2, int* sum );
4、打开cmd命令窗口,进入gsoaptest目录
输入命令soapcpp2.exe add.h
执行时的警告不用理会。
执行完命令后,目录会有下面文件
add.add.req.xml
add.add.res.xml
add.h
add.nsmap
add.wsdl
ns.xsd
soapC.cpp
soapClient.cpp
soapClientLib.cpp
soapcpp2.exe
soapH.h
soapServer.cpp
soapServerLib.cpp
soapStub.h
5、复制gsoap-2.8\gsoap目录下的下面2个文件到gsoaptest目录
stdsoap2.cpp
stdsoap2.h
6、经过以上步骤,已经产生出C/C++源代码了,接下来要创建一个服务端和客户端
7、建立一个控制台工程,名字为server,在工程下面新建一个addserver.cpp的源文件
源代码如下
#include <stdio.h>
#include <stdlib.h>
#include "stdsoap2.h"
#include "add.h"
#include "add.nsmap"
int main(int argc, char* argv[])
{
int m, s;
struct soap add_soap;
soap_init(&add_soap);
//soap_set_namespaces(&add_soap, add_namespaces);
if (argc < 2)
{
printf("usage: %s <server_port> \n", argv[0]);
exit(1);
}
else
{
m = soap_bind(&add_soap, NULL, atoi(argv[1]), 100);
if (m < 0)
{
soap_print_fault(&add_soap, stderr);
exit(-1);
}
fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
while(true)
{
s = soap_accept(&add_soap);
if (s < 0)
{
soap_print_fault(&add_soap, stderr);
exit(-1);
}
fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);
soap_serve(&add_soap);//该句说明该server的服务
soap_end(&add_soap);
}
}
return 0;
}
//server端的实现函数与add.h中声明的函数相同,但是多了一个当前的soap连接的参数
int ns__add(struct soap *add_soap, int num1, int num2, int *sum)
{
*sum = num1 + num2;
return 0;
}
8、向server工程添加其他文件,
add.h、soapH.h、soapStub.h、stdsoap2.h、soapC.cpp、soapServer.cpp、stdsoap2.cpp
9、编译工程server,如果有编译错误,修改编译错误。
我这里遇到了找不到头文件的错误。
修改如下:[属性 -> 配置属性 -> C/C++ -> 附加包含目录]添加头文件的目录
10、工程编译成功后,可以通过如下方式检测生成的服务端程序
打开cmd,进入server.exe的目录,运行server.exe 4567,
在IE中输入http://localhost:4567,如果显示xml页面,说明程序已经启动。
11、建立一个控制台工程,名字为client,在工程下面新建一个addclient.cpp的源文件
源代码如下
#include <stdio.h>
#include <stdlib.h>
#include "stdsoap2.h"
#include "soapH.h"
#include "add.nsmap"
int add(const char* server, int num1, int num2, int *sum);
// argv[1]:num1 argv[2]:num2 argv[3]:"http://localhost:4567"
int main(int argc, char **argv)
{
int result = -1;
char server[64] = {0};
int num1 = 0;
int num2 = 0;
int sum = 0;
if( argc < 4 )
{
printf("usage: %s num1 num2 http://localhost:4567\n", argv[0]);
exit(0);
}
strncpy(server, argv[3], sizeof(server));
num1 = atoi(argv[1]);
num2 = atoi(argv[2]);
result = add(server, num1, num2, &sum);
if (result != 0)
{
printf("soap err,errcode = %d\n", result);
}
else
{
printf("%d+%d=%d\n", num1, num2, sum );
}
return 0;
}
int 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, add_namespaces);
// 该函数是客户端调用的主要函数,后面几个参数和add.h中声明的一样,前面多了3个参数,
// 函数名是接口函数名ns__add前面加上soap_call_
soap_call_ns__add( &add_soap, server, "", num1, num2, sum );
if(add_soap.error)
{
printf("soap error:%d,%s,%s\n",
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;
}
12、向client工程添加其他文件,
add.h、soapH.h、soapStub.h、stdsoap2.h、soapC.cpp、soapClinet.cpp、stdsoap2.cpp
13、编译工程client,如果有编译错误,修改编译错误。
14、工程编译成功后,
打开cmd,进入client.exe的目录,运行client.exe 1 2 http://localhost:4567
执行结果会出现在cmd窗口:1+2=3
15、如果server.exe与client.exe两个文件在两台不同的电脑上,
那么将client.exe的参数改为响应的IP地址即可
抓包如下:
POST / HTTP/1.1
Host: 192.168.0.106:4567
User-Agent: gSOAP/2.8
Content-Type: text/xml; charset=utf-8
Content-Length: 467
Connection: close
SOAPAction: ""
<?xml version="1.0" encoding="UTF-8"?>
<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:add">
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<ns:add>
<num1>12345</num1>
<num2>23456</num2>
</ns:add>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
HTTP/1.1 200 OK
Server: gSOAP/2.8
Content-Type: text/xml; charset=utf-8
Content-Length: 463
Connection: close
<?xml version="1.0" encoding="UTF-8"?>
<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:add">
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<ns:addResponse>
<sum>35801</sum>
</ns:addResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
参考:http://blog.youkuaiyun.com/wangjian8006/article/details/14453215