gSoap的初步学习——1

本文中使用的gSoap版本是2.8.17的,采用的编译器是VS2008。下面先简要介绍下gSoap的相关知识。

一、gSoap基础知识简介

2.1 wsdl2h
      wsdl2h的使用方法:
           wsdl2h -o 头文件名 WSDL文件名或URL   
      wsdl2h常用选项
    • -o 文件名,指定输出头文件
    • -n 名空间前缀 代替默认的ns
    • -c 产生纯C代码,否则是C++代码
    • -s 不要使用STL代码
    • -t 文件名,指定type map文件,默认为typemap.dat
    • -e 禁止为enum成员加上名空间前缀

2.2  soapcpp2

soapcpp2的使用方法:
<span style="font-weight: normal;"><span style="font-family:SimSun;font-size:18px;">soapcpp2 头文件.h</span></span>
<span style="font-weight: normal;"><span style="font-family:SimSun;font-size:18px;">soapcpp2 ayandy.h</span></span>

将生成下面这些文件

  • soapStub.h    // soap的存根文件,定义了ayandy.h里对应的远程调用模型
  • soapC.c soapH.h // soap的序列和反序列代码,它已经包含了soapStub.h,服务器端与客户端都要包含它
  • soapClient.c soapClientLib.c // 客户端代码,soapClientLib.c文件则只是简单地包含soapClient.c和soapC.c
  • soapServer.c soapServerLib.c // 服务器端代码,soapServerLib.c文件则只是简单地包含soapServer.c和soapC.c
  • ServiceSoap.nsmap ServiceSoap12.nsmap // 名空间定义,服务器端与客户端都要包含它
  • soapServiceSoapProxy.h soapServiceSoap12Proxy.h // 客户端的C++简单包装(如果头文件是纯C代码,这两个文件就不会生成) 
    soapcpp2常用选项
    • -C 仅生成客户端代码
    • -S 仅生成服务器端代码
    • -L 不要产生soapClientLib.c和soapServerLib.c文件
    • -c 产生纯C代码,否则是C++代码(与头文件有关)
    • -I 指定import路径(见上文)
    • -x 不要产生XML示例文件
    • -i 生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。

三、gSoap使用实例

     本例中gSoap的目录D:\Language\gsoap\gsoap-2.8

3.1.Web Service服务端(C++)

[1]新建空的Win32控制台项目“MyFirstWS”。然后添加一个头文件“MyInterface.h”,输入你要暴露给WS客户端的方法声明,内容如下

int   ns__sqrt(double a, double &result);

[2]将D:\Language\gsoap\gsoap-2.8\gsoap\bin\win32中soapcpp2.exe复制到新建的win32项目目录中,在CMD中打开win32项目文件夹,运行命令“soapcpp2  -S  MyInterface.h”生成存根文件

将新生成的C++的源码文件加入到你的工程项目中,soapServerLib.cpp文件不用加。你需要修改自动生成的ns.wsdl文件(可用Notepad等方式打开该文件,在文件的末端可以找到侦听的端口),因为里面的Web Service侦听端口默认为80,但是我们一般不使用默认侦听端口。

[3]加入“D:\Language\gsoap\gsoap-2.8\gsoap”下的“stdsoap2.hstdsoap2.cppdom.cpp(可不要)”三个源文件到当前项目中。

[4]添加一个源文件,命名为:MyFirstWS.cpp,源文件内容如下

// MyFirstWS.cpp : Defines the entry point for the console application.
//
#include <tchar.h>
#include "MyInterface.h"
#include "ns.nsmap"

//我的接口实现
int ns__sqrt(struct soap *soap, double a, double &result)  
{  
	if (a >= 0)  
	{  
		result = sqrt(a);  
		return SOAP_OK;  
	}  

	return soap_sender_fault(soap, 
		"Square root of negative value", 
		"I can only compute the square root of a non-negative value"); 
} 

//返回接口描述,否则在为C#代码添加服务引用时,找不到这个接口
int http_get(struct soap   *soap) 
{ 
	std::string fileName = "ns.wsdl";

	if(strstr(soap->msgbuf,"clientaccesspolicy.xml")!=NULL){
		fileName = "clientaccesspolicy.xml";

	}//红色乃添加的代码
	FILE*fd = NULL;
	fd = fopen(fileName.c_str(), "rb"); //open WSDL file to copy
	if (!fd)
	{
		return 404; //return HTTP not found error
	}
	soap->http_content = "text/xml";  //HTTP header with text /xml content
	soap_response(soap,SOAP_FILE);
	for(;;)
	{
		size_t r = fread(soap->tmpbuf,1, sizeof(soap->tmpbuf), fd);
		if (!r)
		{
			break;
		}
		if (soap_send_raw(soap, soap->tmpbuf, r))
		{
			break; //cannot send, but little we can do about that
		}
	}
	fclose(fd);
	soap_end_send(soap);
	return SOAP_OK; 
}

int _tmain(int argc, _TCHAR* argv[])
{
	int m, s; /* master and slave sockets */

	//初始化soap环境变量
	struct soap sqrt_soap;
	soap_init(&sqrt_soap);

	//添加,返回接口描述(WSDL)的功能,
	//否则其它语言在建立Web Service客户端的时候,无法自动生成代码
	sqrt_soap.fget = http_get;    

	//服务端侦听端口设为8080,注意ns.wsdl文件内容要做相应修改
	m = soap_bind(&sqrt_soap, NULL, 8080, 100);
	if (m < 0)
	{
		soap_print_fault(&sqrt_soap, stderr);
		exit(-1);
	}

	fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
	for ( ; ; )
	{ 
		s = soap_accept(&sqrt_soap); 
		if (s < 0)
		{ 
			soap_print_fault(&sqrt_soap, stderr);
			exit(-1);
		}
		fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);

		soap_serve(&sqrt_soap);
		soap_end(&sqrt_soap);
	}

	return 0;
}

3.2 WebService客户端(C++语言)

[1]新建C++Console工程,运行3.1中创建的WebService服务端(这步很重要)

[2]将gSoap中的wsdl2h.exe和soapcpp2.exe复制到新建工程目录中,根据http://localhost:8080/网址打印出的WSDL信息产生MyInterface.h头文件,在CMD中打开新建工程的目录文件夹,然后输入下面命令

wsdl2h  -o  MyInterface.h  http://localhost:8080/

[3]根据“MyInterface.h”头文件生成存根文件

soapcpp2  -i -C  -I D:\Language\gsoap\gsoap-2.8\gsoap\import MyInterface.h

-C”参数指定只生成客户端存根文件,默认服务端和客户端存根文件都生成。“-I”参数指定stlvector.h文件的搜索路径。“D:\Language\gsoap\gsoap-2.8\gsoap\import”是我gsoap  Toolkit的存放路径。在项目中添加新生成的源文件,soapClientLib.cpp文件不用添加。

[4]在项目中添加D:\Language\gsoap\gsoap-2.8\gsoap\目录下的stdsoap2.hstdsoap2.cppdom.cpp三个文件。

[5]修改项目默认的cpp文件,源码清单如下

// MyFirstWSClient.cpp : Defines the entry point for the console application.
//
//服务端提供的功能可以查看下面的头文件内容
//如果服务端的URL地址或侦听端口改变,需要修改下面这个头文件
#include "soapServiceProxy.h"

//下面这个头文件是必须的,否则stdsoap2.obj连接的时候会出错
#include "Service.nsmap"
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
	ServiceProxy srv;

	double dR;

	_ns2__sqrt         call;      //形参表
	_ns2__sqrtResponse response;  //返回调用结果
	call.a = 4.0;
	int nR = srv.sqrt(&call,&response);//调用sqrt函数
	if( nR == SOAP_OK)
	{
		dR = response.result;
		printf("成功返回,sqrt(4)=%f\n",response.result);
	} else
	{
		printf("请检查网络连接!");
	}
    while(1);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值