我的gsoap创建客户端网络代理过程-创新互联
2017年06月11日16:42:58
创新互联建站主营临澧网站建设的网络公司,主营网站建设方案,app软件开发公司,临澧h5重庆小程序开发搭建,临澧网站营销推广欢迎临澧等地区企业咨询这几天做了一个售电接口(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
另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
网页题目:我的gsoap创建客户端网络代理过程-创新互联
网页网址:http://scyanting.com/article/cohihj.html