gSOAP 初體驗

安裝

因爲本人使用的是 Mac OS 系統,故以 Mac OS 爲例說明如何安裝 gSOAP。html

1)下載 gSOAP

能夠在 https://sourceforge.net/projects/gsoap2 下載最新版本的 gSOAP。c++

2)安裝 flex, bison, openssl

能夠使用brew install進行安裝:bash

brew install flex bison openssl

3)編譯安裝 gSOAP

解壓上面下載的 gSOAP,而後執行下面的命令:app

cd gsoap-2.8 ./configure --with-openssl=/usr/local/opt/openssl make sudo make install

安裝完成,會出現如下的提示: 
框架

安裝中若是出現 fatal error: 'openssl/bio.h' file not found 的錯誤,能夠經過嘗試從新安裝 openssl 和使用最新的 gsoap-2.8 版本的方法來解決,具體解決辦法也能夠 google 一下。dom

其餘平臺的安裝教程能夠參考官方文檔:https://www.genivia.com/downloads.htmlide

gSOAP 工具

gSOAP 提供了兩個工具來方便開發人員使用 C/C++ 語言快速開發Web 服務應用,經過 gSOAP 提供的這兩個工具,開發人員能夠快速生成服務端與客戶端代碼框架,接下來開發人員只須要實現具體的接口函數便可。函數

wsdl2h

wsdl2h 工具根據 WSDL 文件生成 C/C++ .h 頭文件。 
WSDL(Web Service Description Language)即 Web 服務描述語言,它使用 XML 來對 Web 服務進行描述。 
wsdl2h 的用法:工具

wsdl2h -o 頭文件名 WSDL文件名或URL

例如:測試

wsdl2h -o calc.h http://www.genivia.com/calc.wsdl

wsdl2h 根據 URL 指定的 WSDL 生成calc.h頭文件。calc.h對 Web 服務接口進行定義。

wsdl2h 支持額外的參數:

  • -s 生成的頭文件不使用 STL
  • -o 文件名,指定輸出頭文件的名稱
  • -c 產生純 C 代碼,不然是 C++ 代碼
  • -t 文件名,指定 type map 文件,默認是 typemap.dat

soapcpp2

soapcpp2 工具則從上面生成的頭文件生成 SOAP 服務端和客戶端框架代碼。例如對於上面的cacl.h,使用 soapcpp2 命令:

soapcpp2 -i -Iimport calc.h

soapcpp2 也支持額外的參數:

  • -i 生成 C++ 包裝類,客戶端爲 xxxProxy.h(.cpp),服務端爲xxxService.h(.cpp)
  • -I 指定 import 的路徑,好比須要引入stlvector.h文件來支持 STL vector 的序列化
  • -C 僅生成客戶端代碼
  • -S 僅生成服務端代碼
  • -c 產生純 C 代碼,不然是 C++ 代碼
  • -x 不要產生 XML 示例文件
  • -L 不要產生soapClientLib.csoapServerLib.c文件

例子

gSOAP 中包含了大量的例子以便讓開發人員快速瞭解如何使用 gSOAP 開發 Web 服務。 
咱們以 gSOAP 的 samples 目錄下的 calc++ 的代碼爲例,說明如何使用 gSOAP 來編寫客戶端和的服務端代碼。

calc++ 目錄已經包含了 calc.h 頭文件,這個頭文件跟上面咱們使用 wsdl2h 生成的 calc.h 頭文件並不徹底相同,爲了實驗的方便,咱們使用 calc++ 目錄的calc.h 頭文件進行實驗。

calc.h頭文件:

//gsoap ns service method: add Sums two values int ns__add(double a, double b, double *result); //gsoap ns service method: sub Subtracts two values int ns__sub(double a, double b, double *result); //gsoap ns service method: mul Multiplies two values int ns__mul(double a, double b, double *result); //gsoap ns service method: div Divides two values int ns__div(double a, double b, double *result); //gsoap ns service method: pow Raises a to b int ns__pow(double a, double b, double *result);

而後,咱們使用 soapcpp2 工具來生成客戶端和服務端的框架代碼:

soapcpp2 -i calc.h

客戶端代碼

calcclient.c++ 代碼:

#include "soapcalcProxy.h" #include "calc.nsmap" const char server[] = "http://127.0.0.1:8080"; int main(int argc, char **argv) { if (argc < 4) { fprintf(stderr, "Usage: [add|sub|mul|div|pow] num num\n"); exit(0); } double a, b, result; a = strtod(argv[2], NULL); b = strtod(argv[3], NULL); calcProxy calc; calc.soap_endpoint = server; switch (*argv[1]) { case 'a': calc.add(a, b, &result); break; case 's': calc.sub(a, b, &result); break; case 'm': calc.mul(a, b, &result); break; case 'd': calc.div(a, b, &result); break; case 'p': calc.pow(a, b, &result); break; default: fprintf(stderr, "Unknown command\n"); exit(0); } if (calc.error) calc.soap_stream_fault(std::cerr); else printf("result = %g\n", result); return 0; }

因爲代碼使用 STL,爲了順利編譯經過,須要將 gSOAP 中的stdsoap2.cppstdsoap2.h文件拷貝到客戶端和服務端代碼所在的目錄。 
改寫好客戶端代碼後,使用 g++ 進行編譯:

g++ -o calcclient++ calcclient.cpp soapC.cpp soapcalcProxy.cpp stdsoap2.cpp

編譯順利經過。

服務端代碼

calcserver.cpp代碼以下,其中能夠指定服務端的端口號:

#include "soapcalcService.h" #include "calc.nsmap" int main(int argc, char **argv) { calcService calc; if (argc < 2) calc.serve(); /* serve as CGI application */ else { int port = atoi(argv[1]); if (!port) { fprintf(stderr, "Usage: calcserver++ <port>\n"); exit(0); } /* run iterative server on port until fatal error */ if (calc.run(port)) { calc.soap_stream_fault(std::cerr); exit(-1); } } return 0; } int calcService::add(double a, double b, double *result) { *result = a + b; return SOAP_OK; } int calcService::sub(double a, double b, double *result) { *result = a - b; return SOAP_OK; } int calcService::mul(double a, double b, double *result) { *result = a * b; return SOAP_OK; } int calcService::div(double a, double b, double *result) { if (b) *result = a / b; else { char *s = (char*)soap_malloc(this, 1024); (SOAP_SNPRINTF(s, 1024, 100), "<error xmlns=\"http://tempuri.org/\">Can't divide %f by %f</error>", a, b); return soap_senderfault("Division by zero", s); } return SOAP_OK; } int calcService::pow(double a, double b, double *result) { *result = ::pow(a, b); if (soap_errno == EDOM) /* soap_errno is like errno, but compatible with Win32 */ { char *s = (char*)soap_malloc(this, 1024); (SOAP_SNPRINTF(s, 1024, 100), "<error xmlns=\"http://tempuri.org/\">Can't take power of %f to %f</error>", a, b); return soap_senderfault("Power function domain error", s); } return SOAP_OK; }

而後使用 g++ 來對服務端代碼進行編譯:

g++ -o calcserver++ calcserver.cpp soapC.cpp soapcalcService.cpp stdsoap2.cpp

編譯一樣順利經過。

測試

運行上面編譯好的calcservercalcclient可執行文件 
來對 Web 服務進行測試,測試結果以下:

 

轉自:https://blog.csdn.net/lihao21/article/details/70168050

參考資料

    1. https://www.cs.fsu.edu/~engelen/soapdoc2.html
    2. https://www.genivia.com/downloads.html
    3. https://www.genivia.com/dev.html
    4. http://blog.csdn.net/yangjun1115/article/details/29360389
    5. https://www.cs.fsu.edu/~engelen/calc.html
    6. http://commandos.blog.51cto.com/154976/130652
    7. http://www.cppblog.com/qiujian5628/archive/2008/10/11/54019.html
    8. http://blog.sina.com.cn/s/blog_5ee9235c0100de3g.html
相關文章
相關標籤/搜索