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

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常用选项

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

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

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

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

soapcpp2  -j  test.h

soapcpp2常用选项

  • -C 仅生成客户端代码
  • -S 仅生成服务器端代码
  • -L 不要产生soapClientLib.c和soapServerLib.c文件
  • -c 产生纯C代码,否则是C++代码(与头文件有关)
  • -I 指定import路径(见上文)
  • -x 不要产生XML示例文件
  • -i生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。
  • -j 和-i类似,区别在于生成的代理类不继承于soap struct,而是包含了一个soap的指针。此种方式生成的代理类便于相互通信

将生成下面这些文件

  • soapStub.h// soap的存根文件,定义了test.h里对应的远程调用模型
  • soapC.csoapH.h //soap的序列和反序列代码,它已经包含了soapStub.h,服务器端与客户端都要包含它
  • soapClient.csoapClientLib.c //C客户端代码,soapClientLib.c文件则只是简单地包含soapClient.c和soapC.c
  • soapServer.csoapServerLib.c //C服务器端代码,soapServerLib.c文件则只是简单地包含soapServer.c和soapC.c
  • ServiceSoap.nsmapServiceSoap12.nsmap // 名空间定义,服务器端与客户端都要包含它
  • soapServiceSoapProxy.hsoapServiceSoap12Proxy.h //客户端的C++简单包装(如果头文件是纯C代码,这两个文件就不会生成)

综上所述

  • 如果编写服务器端C方式,需要的文件就有:soapStub.h、soapC.cpp  soapH.h  soapServer.c  soapServerLib.c  ServiceSoap.nsmap  ServiceSoap12.nsmap  soapServiceSoapProxy.h  soapServiceSoap12Proxy.h
  • 如果编写客户端C++方式,需要的文件就是:soapStub.h  soapC.cpp  soapH.h  soapXXXXSoapProxy.cpp  soapXXXXSoapProxy.h  soapXXXXSoapService.cpp  soapXXXXSoapService.h  XXXXSoap.nsmap
  • 当然,还要加入gsoap库里的stdsoap2.cpp文件(如果是写C代码,则加入stdsoap2.c)【在gsoap根目录下,不同版本的gsoap对应的该文件是不同的,不可以混用】
  • 到这里test.h已经没用了

如果看到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

时间: 2024-10-07 18:47:37

我的gsoap创建客户端网络代理过程的相关文章

利用IDEA创建Web Service服务端和客户端的详细过程

创建服务端 一.file–>new–>project 二.点击next后输入服务端名,点击finish,生成目录如下 三.在 HelloWorld.Java 文件中右击,选 WebServices ,再选 Generate Wsdl From Java Code ,确定 点击ok会自动给我们生成HelloWorld.wsdl,画红线处注意 四.配置tomcat,此处不多说,主要是配置好tomcat后还需要加入 Axis 的库 点击右下角fix即可,重新启动 tomcat ,在浏览器中输入:ht

网络代理的基础知识

常见的网络代理技术有vpn代理,http代理,socket代理等.打开fireFox浏览器看见其常见网络连接配置很多,本文将逐步讲解其每项代理的意义及配置方法: 一.Socks原理介绍 1.Socket套接字介绍 Socket套接字实际上是基于TCP/IP的一组应用程序接口,应用层的程序通过调用Socket套接字来实现网络间的进程通信. 2.Socks5原理介绍 Socks5是一个代理协议,位于传输层(TCP/UDP等)与应用层之间.Socks软件包组成为如下结构: Socks库:安装于客户端.

使用Gsoap创建webservice(c++)

使用Gsoap创建WebService (c++) 1.         下载编译Gsoap gSOAP工具包是用于SOAP和REST XML Web服务以及通用C / C ++ XML数据绑定的C和C ++软件开发工具包. 该工具包分析WSDL和XML模式(单独或作为组合集),并将XML模式类型和SOAP / REST XML消息传递协议映射为易于使用且高效的C和C ++代码. 它还支持通过自动生成XML序列化代码和WSDL规范将(传统)C和C ++应用程序作为XML Web服务公开. 下载G

Docker网络代理设置

背景 在一些实验室环境,服务器没有直接连接外网的权限,需要通过网络代理.我们通常会将网络代理直接配置在/etc/environment./etc/profile之类的配置文件中,这对于大部分操作都是可行的.然而,docker命令却使用不了这些代理.比如docker pull时需要从外网下载镜像,就会出现如下错误: $ docker pull hello-world Unable to find image 'hello-world:latest' locally Pulling reposito

2015/10/4 iOS 笔记 细节 简单-代理过程 UITableView

一.简单-代理过程 1,创建代理 @class TgFootView; @protocol TgFootViewDelegate <NSObject> @optional   可选是否实现 视图的下载按钮被点击 - (void)tgFootViewDidDownloadButtonClick:(TgFootView *)footView; @end @interface TgFootView : UIView 代理如果使用强引用,就会产生循环引用,造成控制器和子视图都无法被释放,造成内存泄露.

创建VMkernel网络

VMkernel网络接口为主机提供网络连接,并且处理VMware vMotion.IP存储器和Fault Tolerance. 在主机之间移动虚拟机的过程为迁移.使用vMotion,可以在不停机的情况下迁移已打开电源的虚拟机,但是必须设置正确的VMkernel网络连接堆栈以适应vMotion.IP存储器是指使用TCP/IP网络的ESXi的任何形式的存储器.由于这些存储器类型都基于网络,因此他们可以使用相同的VMkernel接口和端口组.创建VMkernel网络的步骤如下. 步骤1 在主机的配置选

3proxy安装及配置网络代理的流程

3proxy安装及配置网络代理的流程 3proxy的官网在:https://3proxy.ru/ ,3proxy可以用来设置各种协议的代理,比如说http,socks等,关于3proxy的详细介绍可以通过搜索来了解,这里就不说了. 安装 3proxy的代码代管在github上面,地址是:https://github.com/z3APA3A/3proxy 安装步骤如下: git clone https://github.com/z3APA3A/3proxy.git,直接通过git把代码复制到本地(

SDNLAB技术分享(四):利用ODL下发流表创建VxLAN网络

邓晓涛,当前就职于江苏省未来网络创新研究院,是CDN团队的一名研发人员,主要从事SDN相关的研发相关工作.曾就职于三星电子于先行解决方案研发组任高级工程师.思科系统于云协作应用技术部(CCATG)任工程师.-----------------------------------------------------------------------------------------------------[分享正文]今天想跟大家分享如何通过ODL控制器下发流表来创建VxLAN网络.ODL作为当前

创建calico网络报错client response is invalid json

使用docker创建calico网络失败. # docker network create --driver calico --ipam-driver calico-ipam testcalico Error response from daemon: failed to update store for object type *libnetwork.endpointCnt: client: response is invalid json. The endpoint is probably