VS2008 gsoap 笔记


材料

Gsoap下载地址:

https://sourceforge.net/projects/gsoap2/files/gSOAP/

 

用户使用说明地址:

http://www.genivia.com/doc/soapdoc2.html

http://www.phpstudy.net/e/wsdl/index.html

 

相关参考链接在文章末尾。

soapcpp2.exewsdl2h.exe工具具体说明请看下面链接

http://blog.csdn.net/guxch/article/details/8332701



源码下载地址:

http://download.csdn.net/detail/qqwoaidushu88/9587879 



开始搞

下载,打开上面的下载地址,我选的是gsoap_2.8.33.zip 版本,点击后下载,下载后解压。

 

先照着CSND的文章做一个简单的两个整数加法例子。

步骤1:相关文件生成,新建个文件夹我把它命名为 myFirstGsoapTest且放在D盘根目录,把soapcpp2.exe、wsdl2h.exe这两个文件拷到myFirstGsoapTest目录下

 

步骤2:拷贝stdsoap2.hstdsoap2.cpp两个文件到myFirstGsoapTest目录下(这两个文件可以不用拷贝,这里只是为了待会儿生成相关文件后方便拷贝到工程目录下),文件所在位置是gsoap_2.8.33\gsoap-2.8\gsoap\

 

 

步骤3接下来就是创建空项目,命名为Server

 


步骤4在myFirstGsoapTest目录下新建一个add.h文件,打开后并编辑复制黏贴下面的代码,包括注释(这些注释在C++中是没用的但是soapcpp2.exe会根据它命名一些输出的文件)。

//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 );

 

 

 

头文件中 函数名要用ns__开头,如果是std::string类型要用 typedef std::string xsd__string;这样gsoap内部便于生成wsdlxml(网上是这么说的);ns__中是两个_

 

步骤5:接着就是生成相关文件

打开cmd 进到D:\myFirstGsoapTest\目录下,输入“soapcpp2.exe  add.h”回车就可以生成默认的文件,这里我没使用参数,如果想使用参数可以根据工具具体说明自己玩一下。

 

执行完后再看D:\myFirstGsoapTest\目录,多出一些文件。

 

以上这五步是生成客户端和服务端两者所需的文件,在生成这些文件的基础上接下来就是服务端的实现。

步骤6:服务端

然后选择add.nsmapsoapC.cppsoapC.hsoapServer.cppsoapStub.hadd.hstdsoap2.cppstdsoap2.h,拷贝到D:\myFirstGsoapTest\Server\Server目录下

 

 


 

步骤7:在工程里添加Server.spp

 

 

步骤8:加入以下代码

 

#include <stdio.h>
#include "add.h"
#include "add.nsmap"

int main(int argc, char* argv[])
{

	int m, s; /* master and slave sockets */
	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);
		for ( ; ; )
		{ 
			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;
	printf("%d+%d=%d\n",num1,num2,*sum);
	return 0;
}

步骤9:添加WS2_32.lib

 

步骤10:修改输出(为了方便命令行运行)

 

步骤11尝试编译,有错就修改。

 

步骤12:回到命令行,输入Server.exe 8888 回车

 

步骤13另外启动一个cmd使用telnet命令检测9999端口是否被打开了,如果显示的是一个光标在闪那就是打开了。

 

步骤14客户端

再在D:\myFirstGsoapTest创建一个客户端空工程命名为Client,步骤同上。

步骤15:创建好后选择add.nsmapsoapC.cppsoapC.hsoapClient.cppsoapStub.hadd.hstdsoap2.cppstdsoap2.h,拷贝到D:\myFirstGsoapTest\Client\Client目录下(注意与服务端不同的是拷贝soapClient.cpp

 

步骤16:并添加现有项到工程,再创建Client.cpp文件,添加wsock32.lib动态库,同服务端一样修改输出目录为D:\myFirstGsoapTest\。

拷贝以下代码:

#include <stdio.h>
#include <stdlib.h>
#include "soapH.h"
#include "add.nsmap"

int add(const char* server, int num1, int num2, int *sum);

int main(int argc, char **argv) 
{
	int result = -1;
	char* server="http://localhost:9999";
	int num1 = 0;
	int num2 = 0;
	int sum = 0;
	if( argc < 3 )
	{
		printf("usage: %s num1 num2 \n", argv[0]);
		exit(0);
	}

	num1 = atof(argv[1]);
	num2 = atof(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中声明的一样,前面多了个参数,函数名是接口函数名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;
}

编译,注意这个端口要和服务端一致,不然连不上;

 

 

步骤17再用cmd测试,进入D:\myFirstGsoapTest\目录  输入Client.exe  4  5

 

多次测试程序可以达到两个整数的加法操作。

 

 

 

结构体

其实大部分时候的需求都是去获取数据,比如获取一个用户的基本信息,通常会用结构体来保存一个用户的信息比如

struct user{
	char gender;
	int age;
	int UID;
	char* name;
};

 

先看下网上的说法

 

 

结构体要ns__开头,且要有父结构体,那就照着写

 

struct ns__user{
	char gender;
	int age;
	int UID;
	char* name;
};


//带父结构
struct SingleIn_Out
{
	struct ns__user userInfo;
};

 

步骤1D:\myFirstGsoapTest\目录新建structIO.h,贴入以下代码

#include <string>
//gsoap ns service name: structIO
//gsoap ns service namespace: http://localhost/structIO.wsdl
//gsoap ns service location: http://localhost
//gsoap ns service executable: structIO.cgi
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:structIO

typedef std::string xsd__string;

struct ns__user{
	char gender;
	int age;
	int UID;
	xsd__string name;
};

//结构体
struct SingleIn_Out
{
	struct ns__user userInfo;
};

int ns__add(double a, double b, double *result);

//结构体
int ns__singleInAndOut(struct SingleIn_Out myinput,struct SingleIn_Out&myoutput);

 

步骤2使用命令行生成gsoap所需的文件

 

步骤3:在D:\myFirstGsoapTest\目录创建服务端空项目,命名为StructServer

步骤4:在D:\myFirstGsoapTest\目录创建客户端空项目,命名为StructClient

步骤5:选择structIO.nsmapsoapC.cppsoapC.hsoapServer.cppsoapStub.hstructIO.hstdsoap2.cppstdsoap2.h,拷贝到D:\myFirstGsoapTest\StructServer\StructServer目录下

步骤6:选择structIO.nsmapsoapC.cppsoapC.hsoapClient.cppsoapStub.hstructIO.hstdsoap2.cppstdsoap2.h,拷贝到D:\myFirstGsoapTest\StructClient\StructClient目录下

步骤7:添加现有项到服务端和客户端工程

步骤8:添加Server.cpp文件到服务端,并拷贝以下代码:

#include <stdio.h>
#include "structIO.h"
#include "structIO.nsmap"
#include <iostream>

int main(int argc, char* argv[])
{
	int m, s; /* master and slave sockets */
	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);
		for ( ; ; )
		{ 
			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, double num1, double num2, double *sum)
{
	*sum = num1 + num2;
	printf("%lf+%lf=%lf\n",num1,num2,*sum);
	return 0;
}



//结构体
int ns__singleInAndOut(struct soap *soap,struct SingleIn_Out myinput,struct SingleIn_Out&myoutput)
{
	//输出客户端传入的结构体
	printf("----------------client------------------------\n");
	printf("年龄%d\n",myinput.userInfo.age);
	printf("性别%d\n",myinput.userInfo.gender);
	printf("ID %d\n",myinput.userInfo.UID);
	//printf("姓名%s\n",myinput.userInfo.name);
	std::cout<<"姓名"<<myinput.userInfo.name<<std::endl;

//修改结构体后返回给客户端
	myoutput.userInfo.age	=myinput.userInfo.age+10;
	myoutput.userInfo.gender=myinput.userInfo.gender;
	myoutput.userInfo.UID	=myinput.userInfo.UID+10;
	myoutput.userInfo.name	=myinput.userInfo.name;

	return 0;
}

 

 

步骤9:修改工程输出目录,添加ws2_32.lib动态库,生成项目。

此时vc会报错error C2011: 'ns__user' : 'struct' type redefinition提示结构体重定义,解决的方法就是注释D:\myFirstGsoapTest\StructServer\StructServer\structIO.h结构体定义部分,再重新生成就行了。

 

 

 

步骤10:添加Client.cpp文件到客户端,并拷贝以下代码

 

#include <stdio.h>
#include <stdlib.h>
#include "soapH.h"
#include "structIO.nsmap"
#include <iostream>


int  add(const char* server, double num1, double num2, double *sum);
int singleInAndOut(const char* server,struct SingleIn_Out myinput,struct SingleIn_Out&myoutput);

void testAdd(int argc, char **argv)
{
	double result = -1;
	char* server="http://localhost:8888";
	double num1 = 0;
	double num2 = 0;
	double sum = 0;
	if( argc < 3 )
	{
		printf("usage: %s num1 num2 \n", argv[0]);
		exit(0);
	}

	num1 = atof(argv[1]);
	num2 = atof(argv[2]);

	result = add(server, num1, num2, &sum);
	if (result != 0)
	{
		printf("soap err,errcode = %d\n", result);
	}
	else
	{
		printf("%lf+%lf=%lf\n", num1, num2, sum );
	}
}


void testSingle()
{

	char* server="http://localhost:8888";
	struct SingleIn_Out myinput;
	myinput.userInfo.age=10;
	myinput.userInfo.gender=1;
	myinput.userInfo.UID=1000;
	myinput.userInfo.name="xiaoming";

	printf("----------------begin------------------------\n");
	printf("年龄%d\n",myinput.userInfo.age);
	printf("性别%d\n",myinput.userInfo.gender);
	printf("ID %d\n",myinput.userInfo.UID);
	//printf("姓名%s\n",myinput.userInfo.name);
	std::cout<<"姓名"<<myinput.userInfo.name<<std::endl;

	struct SingleIn_Out myoutput;
	double result = -1;
	result = singleInAndOut(server, myinput, myoutput);

	if (result != 0)
	{
		printf("soap err,errcode = %d\n", result);
	}
	else
	{
		printf("----------------return------------------------\n");
		printf("年龄%d\n",myoutput.userInfo.age);
		printf("性别%d\n",myoutput.userInfo.gender);
		printf("ID %d\n",myoutput.userInfo.UID);
		std::cout<<"姓名"<<myinput.userInfo.name<<std::endl;
	}
}



int main(int argc, char **argv) 
{
	//testAdd(argc,argv);
	testSingle();
	return 0;
}

int add( const char* server, double num1, double num2, double *sum )
{
	struct soap add_soap;
	int result = 0;
	soap_init(&add_soap);
	//    soap_set_namespaces(&add_soap, add_namespaces);

	//该函数是客户端调用的主要函数,后面几个参数和add.h中声明的一样,前面多了个参数,函数名是接口函数名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;
}

int singleInAndOut(const char* server,struct SingleIn_Out myinput,struct SingleIn_Out&myoutput)
{
	//传入结构体
	struct soap add_soap;
	int result = 0;
	soap_init(&add_soap);
	//soap_set_namespaces(&add_soap, add_namespaces);

	//该函数是客户端调用的主要函数,后面几个参数和add.h中声明的一样,前面多了个参数,函数名是接口函数名ns__add前面加上soap_call_
	soap_call_ns__singleInAndOut( &add_soap, server, "", myinput, myoutput);
	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;
}

 

步骤11与服务端相比客户端可以不注释结构体定义生成时也不会报错,修改工程输出目录,添加ws2_32.lib动态库,生成项目。

步骤12:使用命令行启动服务端 端口为8888,再另启一个命令行启动客户端测试。结果如下,完成。

 

 

 

要注意的地方就是服务端要注释结构体定义再生成可执行文件。

 

 

 

 

 

继续,有时需要传入或返回一组用户信息。

那开搞

步骤1D:\myFirstGsoapTest\目录下创建一个structArrayIO.h文件,并拷贝以下代码

//gsoap ns service name: structArrayIO
//gsoap ns service namespace: http://localhost/structArrayIO.wsdl
//gsoap ns service location: http://localhost
//gsoap ns service executable: structArrayIO.cgi
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:structArrayIO

struct ns__user{
	char gender;
	int age;
	int UID;
	char* name;
};

//结构体
struct SingleIn_Out
{
	struct ns__user userInfo;
};

//数组
struct ArryIn_Out
{
	struct ns__user**__ptr;
	int __size;
};


int ns__add(double a, double b, double *result);


//结构体单进单出
int ns__singleInAndOut(struct SingleIn_Out myinput,struct SingleIn_Out&myoutput);

//结构体数组
int ns__arryInAndOut(struct ArryIn_Out myinput,struct ArryIn_Out*myoutput);

 

 

注意结构体红色部分,根据网上的教程 父级结构名字不要带ns__;返回的目标结构成员的名字必须是__ptr,大小的名字必须是__size

 

步骤2:使用命令行soapcpp2.exe  structArrayIO.h生成先关文件

创建空项目,添加文件,设置工程属性之类的步骤就不再说了和上面的一样。

步骤3:服务端添加Server.cpp,并拷贝以下代码。

<pre name="code" class="html">#include <stdio.h>
#include "structArrayIO.h"
#include "structArrayIO.nsmap"
#include <iostream>

int main(int argc, char* argv[])
{
	int m, s; /* master and slave sockets */
	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);
		for ( ; ; )
		{ 
			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, double num1, double num2, double *sum)
{
	*sum = num1 + num2;
	printf("%lf+%lf=%lf\n",num1,num2,*sum);
	return 0;
}



//结构体
int ns__singleInAndOut(struct soap *soap,struct SingleIn_Out myinput,struct SingleIn_Out&myoutput)
{
	//输出传入的结构体
	//修改结构体后返回给客户端
	printf("----------------client------------------------\n");
	printf("年龄%d\n",myinput.userInfo.age);
	printf("性别%d\n",myinput.userInfo.gender);
	printf("ID %d\n",myinput.userInfo.UID);
	std::cout<<"姓名"<<myinput.userInfo.name<<std::endl;

	myoutput.userInfo.age=myinput.userInfo.age+10;
	myoutput.userInfo.gender=myinput.userInfo.gender;
	myoutput.userInfo.UID=myinput.userInfo.UID+10;

	return 0;
}


//结构体数组
int ns__arryInAndOut(struct soap *soap,struct ArryIn_Out myinput,struct ArryIn_Out*myoutput)
{
	//输出传入的数组
	//修改结构体后返回给客户端
	if (myinput.__size<=0)
		return 0;

	myoutput->__size = myinput.__size; 
	myoutput->__ptr = (struct ns__user**)soap_malloc(soap,myinput.__size*sizeof(struct ns__user));  

	printf("-------------------------------------------------------\n");
	for (int cnt=0;cnt<myinput.__size;cnt++)
	{
		printf("%d\n",myinput.__ptr[cnt]->age);
		printf("%d\n",myinput.__ptr[cnt]->gender);
		printf("%d\n",myinput.__ptr[cnt]->UID);
		std::cout<<"姓名"<<myinput.__ptr[cnt]->name<<std::endl;
		printf("\n");

		myoutput->__ptr[cnt] = (struct ns__user*)soap_malloc(soap,sizeof(struct ns__user));  
		(*myoutput->__ptr[cnt]).UID=myinput.__ptr[cnt]->UID+10;  
		(*myoutput->__ptr[cnt]).age=myinput.__ptr[cnt]->age+1;
		(*myoutput->__ptr[cnt]).gender=myinput.__ptr[cnt]->gender; 
		//(*myoutput->__ptr[cnt]).name=myinput.__ptr[cnt]->name; 
		(*myoutput->__ptr[cnt]).name= soap_strdup(soap,myinput.__ptr[cnt]->name);

		printf("%d\n",myoutput->__ptr[cnt]->age);
		printf("%d\n",myoutput->__ptr[cnt]->gender);
		printf("%d\n",myoutput->__ptr[cnt]->UID);
		std::cout<<"姓名"<<myoutput->__ptr[cnt]->name<<std::endl;
		printf("\n");

	}
	return 0;
}

 

 

 

步骤4:客户端添加Client.cpp,并拷贝以下代码。

 

#include <stdio.h>
#include <stdlib.h>
#include "soapH.h"
#include "structArrayIO.nsmap"
#include <iostream>


int add(const char* server, double num1, double num2, double *sum);
int singleInAndOut(const char* server,struct SingleIn_Out myinput,struct SingleIn_Out&myoutput);
int arryInAndOut(const char* server,struct ArryIn_Out myinput,struct ArryIn_Out*myoutput);

void testAdd(int argc, char **argv)
{
	double result = -1;
	char* server="http://localhost:8888";
	double num1 = 0;
	double num2 = 0;
	double sum = 0;
	if( argc < 3 )
	{
		printf("usage: %s num1 num2 \n", argv[0]);
		exit(0);
	}

	num1 = atof(argv[1]);
	num2 = atof(argv[2]);

	result = add(server, num1, num2, &sum);
	if (result != 0)
	{
		printf("soap err,errcode = %d\n", result);
	}
	else
	{
		printf("%lf+%lf=%lf\n", num1, num2, sum );
	}
}


void testSingle()
{

	char* server="http://localhost:8888";
	struct SingleIn_Out myinput;
	myinput.userInfo.age=10;
	myinput.userInfo.gender=1;
	myinput.userInfo.UID=1000;
	myinput.userInfo.name="test";

	printf("----------------begin------------------------\n");
	printf("年龄%d\n",myinput.userInfo.age);
	printf("性别%d\n",myinput.userInfo.gender);
	printf("ID %d\n",myinput.userInfo.UID);
	std::cout<<"姓名"<<myinput.userInfo.name<<std::endl;

	struct SingleIn_Out myoutput;
	double result = -1;
	result = singleInAndOut(server, myinput, myoutput);

	if (result != 0)
	{
		printf("soap err,errcode = %d\n", result);
	}
	else
	{
		printf("----------------return------------------------\n");
		printf("年龄%d\n",myoutput.userInfo.age);
		printf("性别%d\n",myoutput.userInfo.gender);
		printf("ID %d\n",myoutput.userInfo.UID);
		std::cout<<"姓名"<<myoutput.userInfo.name<<std::endl;
	}
}

void testArry()
{
	struct ArryIn_Out  myoutput;
	char* server="http://localhost:8888";

	std::string hhhhh="hjhj";
	myoutput.__size = 5;  
	myoutput.__ptr = (struct ns__user**)malloc(myoutput.__size*sizeof(struct ns__user));  
	myoutput.__ptr[0] = (struct ns__user*)malloc(sizeof(struct ns__user));  
	myoutput.__ptr[0]->UID=1000;  
	myoutput.__ptr[0]->age=20; 
	myoutput.__ptr[0]->gender=1;
	myoutput.__ptr[0]->name=new char[10];//( char* )malloc(10);
	strcpy(myoutput.__ptr[0]->name,"test0");

	myoutput.__ptr[1] = (struct ns__user*)malloc(sizeof(struct ns__user));  
	myoutput.__ptr[1]->UID=1001;  
	myoutput.__ptr[1]->age=21;  
	myoutput.__ptr[1]->gender=1;
	myoutput.__ptr[1]->name=new char[10];//(char*)malloc(10);
	strcpy(myoutput.__ptr[1]->name,"test1");

	myoutput.__ptr[2] = (struct ns__user*)malloc(sizeof(struct ns__user));  
	myoutput.__ptr[2]->UID=1002;  
	myoutput.__ptr[2]->age=22;  
	myoutput.__ptr[2]->gender=1;
	myoutput.__ptr[2]->name=new char[10];//(char*)malloc(10);
	strcpy(myoutput.__ptr[2]->name,"test2");

	myoutput.__ptr[3] = (struct ns__user*)malloc(sizeof(struct ns__user));  
	myoutput.__ptr[3]->UID = 1003;  
	myoutput.__ptr[3]->age=23; 
	myoutput.__ptr[3]->gender=1;
	myoutput.__ptr[3]->name=new char[10];//(char*)malloc(10);
	strcpy(myoutput.__ptr[3]->name,"test3");

	std::string temp="test4";
	myoutput.__ptr[4] = (struct ns__user*)malloc(sizeof(struct ns__user));  
	myoutput.__ptr[4]->UID = 1004;  
	myoutput.__ptr[4]->age=24;
	myoutput.__ptr[4]->gender=1;
	myoutput.__ptr[4]->name=new char[10];//(char*)malloc(10);
	strcpy(myoutput.__ptr[4]->name,temp.c_str());
	


	struct ArryIn_Out myoutput2;

	double result = -1;
	result = arryInAndOut(server, myoutput, &myoutput2);

	if (result != 0)
	{
		printf("soap err,errcode = %d\n", result);
	}
	else
	{
		printf("----------------return------------------------\n");
	}

	for (int i=0;i<myoutput.__size;i++)
	{
		//free(myoutput.__ptr[i]->name);
		delete[] myoutput.__ptr[i]->name;
		free(myoutput.__ptr[i]);
	}
	free(myoutput.__ptr);
}


int main(int argc, char **argv) 
{
	//testAdd(argc,argv);
	//testSingle();
	testArry();
	return 0;
}

int add( const char* server, double num1, double num2, double *sum )
{
	struct soap add_soap;
	int result = 0;
	soap_init(&add_soap);
	//    soap_set_namespaces(&add_soap, add_namespaces);

	//该函数是客户端调用的主要函数,后面几个参数和add.h中声明的一样,前面多了个参数,函数名是接口函数名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;
}

int singleInAndOut(const char* server,struct SingleIn_Out myinput,struct SingleIn_Out&myoutput)
{
	//传入结构体
	struct soap add_soap;
	int result = 0;
	soap_init(&add_soap);
	//soap_set_namespaces(&add_soap, add_namespaces);

	//该函数是客户端调用的主要函数,后面几个参数和add.h中声明的一样,前面多了个参数,函数名是接口函数名ns__add前面加上soap_call_
	soap_call_ns__singleInAndOut( &add_soap, server, "", myinput, myoutput);
	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;
}

int arryInAndOut(const char* server,struct ArryIn_Out myinput,struct ArryIn_Out*myoutput)
{
	//传入结构体
	struct soap add_soap;
	int result = 0;
	soap_init(&add_soap);
	//soap_set_namespaces(&add_soap, add_namespaces);

	//该函数是客户端调用的主要函数,后面几个参数和add.h中声明的一样,前面多了个参数,函数名是接口函数名ns__add前面加上soap_call_
	soap_call_ns__arryInAndOut( &add_soap, server, "", myinput, myoutput);
	printf("----------------return------------------------\n");
	for (int cnt=0;cnt<myoutput->__size;cnt++)
	{
		printf("%d\n",myoutput->__ptr[cnt]->age);
		printf("%d\n",myoutput->__ptr[cnt]->gender);
		printf("%d\n",myoutput->__ptr[cnt]->UID);
		std::cout<<"姓名"<<myoutput->__ptr[cnt]->name<<std::endl;
		printf("\n"); 
	}
	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;
}

 

 

步骤5:生成可执行文件,使用命令行启动服务端8888端口,另启客户端进行测试,结果如下

 

 

我一直没有解释过serverclient的代码为啥要这么写,其实就是依葫芦画瓢,你先复制黏贴。

Server.cpp  main函数的代码可以说是不用修改的,只要实现自己定的那些函数就行,加法操作,结构体操作,结构体数组操作。

Client.cpp相对于服务端就麻烦一点。在代码注释//该函数是客户端调用的主要函数,后面几个参数和add.h中声明的一样,前面多了个参数,函数名是接口函数名ns__add前面加上soap_call_  告诉了函数的调用和格式。

 

服务端客户端的使用基本有点头目了但还没使用URL xml来传递信息。

 

下面是我在学习和写笔记的时候所参考的一些博客文章先感谢各位博主

参考链接:

WSDL 详解 - ETTTTTSS的专栏 - 博客频道 - CSDN.NET

wsdl生成客户端、wsdl接口测试及简介(有网络和无网络) - 豆丁网

gSoap 服务器和客户端的开发 - zhangxiaonanwin的专栏 - 博客频道 - CSDN.NET

gsoap在windows下的应用 ----服务端(一) - danshiming的日志 - 网易博客

win7 gsoap与vs2010 c++创建Web Service - idealing - 博客园

onvif学习2-soap介绍以及gsoap使用 - 找寻属于自己的瓦尔登湖 - 博客频道 - CSDN.NET

gSoap Visual C++ 2010_飞蚂蚁哥哥_新浪博客

VS2010下用gSoap实现简单加法实例 - 走向辉煌 - 博客频道 - CSDN.NET

gsoap使用心得! - 浪迹天涯 - C++博客

gsoap传递数组方法 - 固本培元的专栏 - 博客频道 - CSDN.NET

gsoap处理http post和http get - jk110333的专栏 - 博客频道 - CSDN.NET

基于gsoap开发WebService服务返回结构体数组 - liang12360640的专栏 - 博客频道 - CSDN.NET

http://blog.csdn.net/flyfish1986/article/details/7593224 gsoap源码分析

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值