天天看點

gSOAP編譯以及測試過程

1.下載下傳源碼。

2.編譯安裝。

3.測試。

1.下載下傳源碼。

直接網上下載下傳最新的源碼即可。

https://sourceforge.net/projects/gsoap2

我下載下傳到的是2.8.111的源碼。

解壓後是

gSOAP編譯以及測試過程

2.編譯安裝。

這個比較簡單,編譯安裝三步走。

./configure

gSOAP編譯以及測試過程

make

一般沒有出錯即可。

make install

安裝成功會把相應的程式安裝到目前系統。

gSOAP編譯以及測試過程
gSOAP編譯以及測試過程

到這裡,我們開發SOAP的兩個工具(wsdl2h、soapcpp2)已經安裝成功。

3.測試。

這裡我們有一個客戶提供的一個wsdl檔案,現在我們就通過這個檔案來生成相應代碼。

首先生成通道wsdl2h 程式生成*.h檔案。指令如下

wsdl2h -o FSUService.h ./FSUService.wsdl

gSOAP編譯以及測試過程

到這裡沒有什麼問題的話應該會生成一個FSUService.h檔案,接下來我們來生成用戶端接口代碼和伺服器接口代碼,執行如下指令

soapcpp2 -i -Iimport FSUService.h

gSOAP編譯以及測試過程

提示成功就可以看到生成的代碼了。

gSOAP編譯以及測試過程

到這裡,目前生成的都是接口代碼,這個需要寫相應的執行代碼才行。

用戶端代碼

client.cpp

#include "soapFSUServiceSoapBindingProxy.h"/*包含接口代碼裡面用戶端代碼*/
#include "FSUServiceSoapBinding.nsmap"/*包含接口代碼裡面對應的nsmap檔案*/

/*以下是伺服器位址*/
const char server[] = "http://172.16.89.202:82/services/FSUSer/FSUService.php?wsdl";
const char server2[] = "http://172.16.89.117:8080";

int main(int argc, char **argv)
{
	std::string str1,result;
  FSUServiceSoapBindingProxy test;
  //test.soap_endpoint = server;
  test.soap_endpoint = server2;
	str1 += "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Request><PK_Type><Name>LOGIN</Name></PK_Type><Info><UserName>admin</UserName><PassWord>21232f297a57a5a743894a0e4a801fc3</PassWord><FSUID>26201907030001</FSUID><FSUIP>172.16.88.192</FSUIP><FSUMAC>00-0c-29-de-4c-58</FSUMAC><FSUVER>1.0.01</FSUVER></Info></Request>";
  test.invoke(str1, result);
 
  if (test.error)
    test.soap_stream_fault(std::cerr);
	else
	{
		printf("client test\r\n");
		std::cout <<	result << std::endl;
	}
	
  test.destroy(); /* clean up mem */
  return 0;
}

server.cpp

#include "soapFSUServiceSoapBindingService.h"/*包含接口代碼裡面服務端代碼*/
#include "FSUServiceSoapBinding.nsmap"/*包含接口代碼裡面對應的nsmap檔案*/

int main(int argc, char **argv)
{
  FSUServiceSoapBindingService test;
  if (argc < 2)
    test.serve();	/* serve as CGI application */
  else
  {
    int port = atoi(argv[1]);
    if (!port)
    {
      fprintf(stderr, "Usage: FSUService++ <port>\n");
      exit(0);
    }
    /* run iterative server on port until fatal error */
    if (test.run(port))
    {
      test.soap_stream_fault(std::cerr);
      exit(1);
    }
  }
  return 0;
} 
``

/*實作一下wsdl檔案裡面的接口*/
int FSUServiceSoapBindingService::invoke(const std::string& _xmlData, std::string &_invokeReturn)
{
  printf("FSUServiceSoapBindingService::invoke");
  _invokeReturn += "FSUServiceSoapBindingService::invoke";
  return SOAP_OK;
} 
           

到這裡用戶端和伺服器測試代碼寫完。

進行編譯之前開需要拷貝一個檔案到工程裡面,就是gsoap裡面的stdsoap2.cpp檔案

路徑是gsoap-2.8/gsoap/stdsoap2.cpp

到到這裡代碼已經全部處理完畢,編譯用戶端和伺服器代碼。

g++ -o client client.cpp soapC.cpp soapFSUServiceSoapBindingProxy.cpp stdsoap2.cpp

g++ -o server server.cpp soapC.cpp soapFSUServiceSoapBindingService.cpp stdsoap2.cpp

編譯一般沒有報錯也沒有警告

gSOAP編譯以及測試過程

執行測試,先開伺服器。

gSOAP編譯以及測試過程

再多一個終端執行用戶端程式

gSOAP編譯以及測試過程

執行了用戶端後,能得到伺服器傳回的字元串即可。

到這裡測試通過。

關于gSOAP工具的應用可以參考部落格

https://www.cnblogs.com/hgwang/p/5840265.html

測試環境是Ubuntu1604,其他環境如果出錯根據實際情況來處理,步驟也是這些。

本機測試雖然已經通過了,但還需要放到arm闆測試。C++的代碼,直接換編譯機編譯既可。

arm-linux-g++ -o client client.cpp soapC.cpp soapFSUServiceSoapBindingProxy.cpp stdsoap2.cpp

編譯的時候會找不到頭檔案(stdsoap2.h),因為我用的編譯伺服器沒有安裝gSOAP元件,安裝需要處理權限,這裡不安裝,直接去拷貝gsoap源碼裡面的gsoap-2.8/gsoap/stdsoap2.h既可

再編譯既可通過

編譯伺服器。

arm-linux-g++ -o server server.cpp soapC.cpp soapFSUServiceSoapBindingService.cpp stdsoap2.cpp

開發過程問題整理:

一、測試過程中出現執行報

[[email protected] FSUService]# ./server 8080

./server: line 4: syntax error: unexpected word (expecting “)”)

這個是編譯器錯誤導緻的,拷貝指令的時候Linux x86的編譯器沒有成功替換為arm-linux-g++,這個編譯是通過的,用file指令檢視檔案屬性發現的。

二、通過網頁通路SOAP服務的時候報

<?xml version="1.0" encoding="UTF-8" ?> 
- <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tmsc="urn:tmsc">
- <SOAP-ENV:Body>
- <SOAP-ENV:Fault SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <faultcode>SOAP-ENV:Client</faultcode> 
  <faultstring>HTTP GET method not implemented</faultstring> 
  </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
  </SOAP-ENV:Envelope>
           

這個是沒有實作http_get(struct soap *soap)導緻的,找到生成的stdsoap2.cpp,找到裡面的http_get(struct soap *soap)函數,在

後面增加如下代碼

FILE*fd = NULL;
fd = fopen("FSUService.wsdl", "rb"); //open WSDL file to copy
if (!fd)
{
	return 404; //return HTTP not found error
}
soap->http_content = "text/xml";  //HTTP header with text /xml content
soap_response(soap,SOAP_FILE);
for(;;)
{
	size_t r = fread(soap->tmpbuf,1, sizeof(soap->tmpbuf), fd);
	if (!r)
	{
		break;
	}
	if (soap_send_raw(soap, soap->tmpbuf, r))
	{
		break; //cannot send, but little we can do about that
	}
}
fclose(fd);
soap_end_send(soap);
return SOAP_OK; 

  //return SOAP_GET_METHOD;//原來的傳回也需要屏蔽或者删除
           

改好重新編譯執行,再通路就可以了,這個問題困擾了好一會兒,看到别人寫的博文給的思路,https://www.cnblogs.com/Laokong-ServiceStation/archive/2011/04/29/2032331.html

測試結果:

Ubuntu虛拟機執行伺服器,arm闆執行用戶端請求成功。

arm闆執行伺服器,Ubuntu虛拟機執行用戶端請求成功。

繼續閱讀