亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

我的gsoap創建客戶端網絡代理過程

發布時間:2020-07-15 09:15:53 來源:網絡 閱讀:789 作者:pq4362050 欄目:建站服務器

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


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

阳信县| 阿拉善盟| 衡山县| 双峰县| 西和县| 湾仔区| 台前县| 商南县| 怀来县| 顺昌县| 永善县| 沧源| 丰镇市| 闸北区| 鲁山县| 紫金县| 合江县| 新化县| 鹿邑县| 资兴市| 遂川县| 高邮市| 潞城市| 柯坪县| 沿河| 楚雄市| 莒南县| 如东县| 叶城县| 大竹县| 辽中县| 墨脱县| 平泉县| 澜沧| 石台县| 伊宁市| 治县。| 定日县| 侯马市| 海阳市| 安阳县|