我的gsoap创建客户端网络代理过程

发布时间:2020-07-15 09:15:53 作者:pq4362050
来源:网络 阅读:792

2017年06月11日16:42:58

这几天做了一个售电接口(windows平台下),包括webservice服务(C#)、webservice动态库、客户端dll(C++)、客户端gsoap代理。软件结构如下:

clientDLL(客户端机器)---->gsoapProxy(客户端机器)------>webservice(服务器)--->webserviceDLL(服务器)---->HSM(加密机)

【强调一下前提,webservice服务是用vs2010创建的web工程,而client是C/C++写的,这里主要介绍如何使用gsoap代理client请求】

由于客户端和服务器不是在同一台机器上,所以使用直接动态调用dll已不可能。C/C++要通过网络去连接服务器,将函数参数传输到webservice的对应函数接口中,就必然要使用某种工具来将函数参数转换到网络格式传输到server,gsoap就是这种强大的工具。gsoap不仅可以代理客户端请求,还可以代理服务端(本次只使用其作为客户端代理)。虽然其已经尽可能做到简单易用,但是我在网络上搜索了好多文章,都是教到生成出文件为止,而如何使用生成出的文件,都是不甚了了。所以我将整个使用过程记录下来,方便以后借鉴。

(一)  下载gsoap软件,网上搜一下,去官方下,然后解压出来,一定要看是否解压完全,在其根目录下有3个文件stdsoap2.h、stdsoap2.cpp 、stdsoap2.c,这个后面要用到的。(我的就是解压过程中电脑好像死机了,但是我没注意,然后没有解压完,害的找了半天stdsoap2这个文件)

(二)生成中间文件

在解压出来的目录下找到wsdl2h.exe   soapcpp2.exe两个文件。

2.1 首先生成中间头文件,作用就是将你的服务端暴露出来的接口生成按网络格式的函数形式。打开命令行窗口,进入到gsoap目录下:【我用的C++方式】

wsdl2h  -s  -o   test.h   http://xxxxx:xxxx/xxx.wsdl

wsdl2h常用选项

后面的***.wsdl是服务端接口说明。如何找到它呢?就我的项目而言,是这样的:

我的webservice是用c#写的,直接使用vs2010创建的web工程,【运行该工程】,就会启动一个web服务了,会弹出浏览器打开一个页面,点击" *****.asmx ",会看到所有的web接口,然后页面上有一个“查看说明”字样的链接,点击应该会进入到 "  ****.wsdl "了,对,就是它。

2.2  根据头文件生产其他文件

soapcpp2  -j  test.h  

soapcpp2常用选项

将生成下面这些文件

综上所述

如果看到soapcpp2提示:”Criticalerror: #import: Cannot open file "stlvector.h" forreading.“, 那是因为我们的头文件使用了STL(wsdl2h没用-s选项),这时要使用-I选项指定gSOAP的import文件路径,这个路径是"$gsoap\gsoap\import":

soapcpp2   -j  test.h -I D:\gsoap-2.7\gsoap\import

(三) 创建代理,入参出参转换,接收返回值

gsoap会将你的服务端接口进行名字转换,而且分成请求和响应两个class(我使用的是C++方式,用起来感觉更简单一些)。

例如:服务端接口为 int  EncryptPurse(char* cardNum, char*  fileMoney, char* dataOut);

gsoap会将该接口转换为:

_ns1__EncryptPurse   【请求类,传递入参】

_ns1__EncryptPurseResponse 【响应类,获取出参和返回值】

创建soap结构体和gsoap代理:

struct  soap  soap;

HSM_USCOREEPSaleSoapProxy  soapProxy; // 类型名字会有不同

定义soap的数据传输格式:

soap_init(&soap);  //Initializes a runtime context

soap_set_mode(&soap, SOAP_C_MBSTRING); //设置数据模式

soapProxy.HSM_USCOREEPSaleSoapProxy_init(SOAP_C_MBSTRING, SOAP_C_MBSTRING);//初始化数据传输模式

然后进行参数转换,注意入参和出参分别在两个类中:

_ns1__EncryptPurse    reqEncryptPurse; //创建请求类对象

_ns1__EncryptPurseResponse  respEncryptPurse;  //创建响应类对象

reqEncryptPurse.cardNum = IncardNo;  // IncardNo为实际传入的参数

reqEncryptPurse.fileMoney = InfileMoney; //InfileMoney为实际传入的参数

respEncyptPurse.dataOut = Outdata;// Outdata为接收出参的参数

接下来调用接口:

int  ret  = soap.EncryptPurse("http://localhost:1132/EPSaleWebService.asmx", NULL, &reqEncryptPurse, respEncryptPurse);

接收返回值和出参

ret = respResponse.EncryptPurseResult;  //接收EncryptPurse的返回值

strcpy(dataOut, respEncryptPurse.dataOut); //接收出参的值

关闭soap,清理内存:

soap_close(&soap);

soap_end(&soap);

soap_done(&soap);

到这里,一个函数接口的请求和相应就完成了.


遇到的问题:

1.最开始编写gsoap工程用的vc6,在编译时报错: sockaddr_storage未定义的类型

由于winsock的版本不一致导致,改到vs2010里再编译就没有该问题了。如果非要在vc6里编译,请继续百度,应该有其他解决方案.

2. error LNK2001: 无法解析的外部符号 _namespaces

  工程--属性--配置属性---C/C++---预处理器, 添加 WITH_NONAMESPACES


推荐阅读:
  1. 如何创建DHCP的中继代理
  2. XenCenter创建VM的过程

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

windows 客户端 gsoap

上一篇:linux为什么自带python

下一篇:如何玩转 SpringBoot 2 快速整合 Listener

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》