使用gSOAP开发实例(2) 股票信息服务端程序

http://blog.csdn.net/yui/article/details/5747433

电信provisioning系统中,常常需要与远程服务器实时交换一些数据,以完成用户的请求。由于简单对象访问协议(Simple Object Access Protocol, SOAP)的流行,许多涉及到第三方的应用,我们一般都比较乐意使用SOAP来开发。不过,由于可能涉及到公司的机密,本系列教程的开发实例尽量采用在网上已经公开的Web Service资源。

 

上文已经交待了gSOAP在Linux环境下的编译方法和客户端的实例程序,本文继续讲解其服务端程序的开发。由于不可能获得真正的数据库内容,我们设定的目标是,所有返回的内容都是客户端传入的股票代码。

 

首先,在gsoap-2.7/gsoap/wsdl/下创建一个stock_server目录

-bash-3.2$ mkdir -p stock_server

 

改变当前路径为stock_server

-bash-3.2$ cd stock_server

 

仍然使用wsdl2h生成基于纯C代码的stock.h

-bash-3.2$ ../wsdl2h -c -o stock.h http://webservice.webxml.com.cn/WebServices/ChinaStockWebService.asmx?wsdl

 

然后,生成服务端存根程序,并且不生成xml文件和soapServerLib.c

-bash-3.2$ ../../bin/linux386/soapcpp2 -S -L -x stock.h

 

**  The gSOAP code generator for C and C++, soapcpp2 release 2.7.17

**  Copyright (C) 2000-2010, Robert van Engelen, Genivia Inc.

**  All Rights Reserved. This product is provided "as is", without any warranty.

**  The soapcpp2 tool is released under one of the following three licenses:

**  GPL, the gSOAP public license, or the commercial license by Genivia Inc.

 

Saving soapStub.h annotated copy of the input declarations

Saving soapH.h interface declarations

Saving soapC.c XML serializers

Saving soapServer.c server request dispatcher

Using ns2 service name: ChinaStockWebServiceSoap

Using ns2 service style: document

Using ns2 service encoding: literal

Using ns2 service location: http://webservice.webxml.com.cn/WebServices/ChinaStockWebService.asmx

Using ns2 schema namespace: http://WebXml.com.cn/ChinaStockWebServiceSoap

Saving ChinaStockWebServiceSoap.nsmap namespace mapping table

Using ns3 service name: ChinaStockWebServiceSoap12

Using ns3 service style: document

Using ns3 service encoding: literal

Using ns3 service location: http://webservice.webxml.com.cn/WebServices/ChinaStockWebService.asmx

Using ns3 schema namespace: http://WebXml.com.cn/ChinaStockWebServiceSoap12

Saving ChinaStockWebServiceSoap12.nsmap namespace mapping table

 

Compilation successful

 

服务端的主程序稍微比客户端复杂些,因为还要处理客户端的其他请求,至少要有其函数体,否则编译时会报错。

 

[cpp]  view plain copy
  1. #include "soapH.h"  
  2. #include "ChinaStockWebServiceSoap12.nsmap"  
  3.   
  4. int main(int argc, char **argv) {  
  5.     if ( argc != 2 ) {  
  6.         printf("Usage: %s port/n", argv[0]);  
  7.         exit(-1);  
  8.     }  
  9.     int port = atol(argv[1]);  
  10.   
  11.     struct soap soap;  
  12.     soap_init(&soap);  
  13.     int m, s;  
  14.     if ( (m = soap_bind(&soap, NULL, port, 100)) < 0 ) {  
  15.         soap_print_fault(&soap, stderr);  
  16.     }  
  17.     else {  
  18.         printf("Socket connect successfully: master socket = %d/n", m);  
  19.         int i = 0;  
  20.         while ( 1 ) {  
  21.             if ( (s = soap_accept(&soap)) < 0 ) {  
  22.                 soap_print_fault(&soap, stderr);  
  23.                 break;  
  24.             }  
  25.             printf("Connection %d accepted from IP = %d.%d.%d.%d, slave socket = %d/n", ++i, (soap.ip >> 24) & 0xff, (soap.ip >> 16) & 0xff, (soap.ip >> 8) & 0xff, soap.ip & 0xff, s);  
  26.             if ( soap_serve(&soap) != SOAP_OK ) {  
  27.                 soap_print_fault(&soap, stderr);  
  28.                 break;  
  29.             }  
  30.             soap_end(&soap);  
  31.         }  
  32.     }  
  33.     soap_done(&soap);  
  34. }  
  35.   
  36. int __ns3__getStockInfoByCode(  
  37.     struct soap *soap,  
  38.     struct _ns1__getStockInfoByCode *request,  
  39.     struct _ns1__getStockInfoByCodeResponse *response) {  
  40.     int element_counter = 25;  
  41.     response->getStockInfoByCodeResult = (struct ns1__ArrayOfString *) malloc(sizeof(struct ns1__ArrayOfString));  
  42.     response->getStockInfoByCodeResult->__sizestring = element_counter;  
  43.     response->getStockInfoByCodeResult->string = (char **) malloc(sizeof(char *) * element_counter);  
  44.     int i = 0;  
  45.     for ( i = 0; i < element_counter; i++ ) {  
  46.         response->getStockInfoByCodeResult->string[i] = (char *) malloc(sizeof(char) * 32);  
  47.         strcpy(response->getStockInfoByCodeResult->string[i], request->theStockCode);  
  48.     }  
  49.     return SOAP_OK;  
  50. }  
  51.   
  52. int __ns3__getStockImage_USCOREkByteByCode(  
  53.     struct soap *soap,  
  54.     struct _ns1__getStockImage_USCOREkByteByCode *request,  
  55.     struct _ns1__getStockImage_USCOREkByteByCodeResponse *response) {  
  56.     return SOAP_OK;  
  57. }  
  58.   
  59. int __ns3__getStockImage_USCOREkByCode(  
  60.     struct soap *soap,  
  61.     struct _ns1__getStockImage_USCOREkByCode *request,  
  62.     struct _ns1__getStockImage_USCOREkByCodeResponse *response) {  
  63.     return SOAP_OK;  
  64. }  
  65.   
  66. int __ns3__getStockImageByteByCode(  
  67.     struct soap *soap,  
  68.     struct _ns1__getStockImageByteByCode *request,  
  69.     struct _ns1__getStockImageByteByCodeResponse *response) {  
  70.     return SOAP_OK;  
  71. }  
  72.   
  73. int __ns3__getStockImageByCode(  
  74.     struct soap *soap,  
  75.     struct _ns1__getStockImageByCode *request,  
  76.     struct _ns1__getStockImageByCodeResponse *response) {  
  77.     return SOAP_OK;  
  78. }  
  79.   
  80. int __ns2__getStockInfoByCode(  
  81.     struct soap *soap,  
  82.     struct _ns1__getStockInfoByCode *request,  
  83.     struct _ns1__getStockInfoByCodeResponse *response) {  
  84.     int element_counter = 25;  
  85.     response->getStockInfoByCodeResult = (struct ns1__ArrayOfString *) malloc(sizeof(struct ns1__ArrayOfString));  
  86.     response->getStockInfoByCodeResult->__sizestring = element_counter;  
  87.     response->getStockInfoByCodeResult->string = (char **) malloc(sizeof(char *) * element_counter);  
  88.     int i = 0;  
  89.     for ( i = 0; i < element_counter; i++ ) {  
  90.         response->getStockInfoByCodeResult->string[i] = (char *) malloc(sizeof(char) * 32);  
  91.         strcpy(response->getStockInfoByCodeResult->string[i], request->theStockCode);  
  92.     }  
  93.     return SOAP_OK;  
  94. }  
  95.   
  96. int __ns2__getStockImage_USCOREkByteByCode(  
  97.     struct soap *soap,  
  98.     struct _ns1__getStockImage_USCOREkByteByCode *request,  
  99.     struct _ns1__getStockImage_USCOREkByteByCodeResponse *response) {  
  100.     return SOAP_OK;  
  101. }  
  102.   
  103. int __ns2__getStockImage_USCOREkByCode(  
  104.     struct soap *soap,  
  105.     struct _ns1__getStockImage_USCOREkByCode *request,  
  106.     struct _ns1__getStockImage_USCOREkByCodeResponse *response) {  
  107.     return SOAP_OK;  
  108. }  
  109.   
  110. int __ns2__getStockImageByteByCode(  
  111.     struct soap *soap,  
  112.     struct _ns1__getStockImageByteByCode *request,  
  113.     struct _ns1__getStockImageByteByCodeResponse *response) {  
  114.     return SOAP_OK;  
  115. }  
  116.   
  117. int __ns2__getStockImageByCode(  
  118.     struct soap *soap,  
  119.     struct _ns1__getStockImageByCode *request,  
  120.     struct _ns1__getStockImageByCodeResponse *response) {  
  121.     return SOAP_OK;  
  122. }  

 

值得注意的是,如果项目中存在多个name space,最好把全部name space的相关方法都进行编码,否则可能出现意想不到的错误:客户端明明是调用ns3的方法,但是服务端却使用了ns2的方法来提供服务。这一点我也比较费解,可能与wsdl本身的写法有关。

 

上述服务端程序的编译命令是

gcc -O2 -o stock_server stock_server.c soapC.c soapServer.c ../../stdsoap2.c -I../.. -L../.. -lgsoap

 

同时,要把上文的客户端程序修改一下,支持指定的end point,不指定end point再取默认的end point

 

[cpp]  view plain copy
  1. #include "soapH.h"  
  2. #include "ChinaStockWebServiceSoap12.nsmap"  
  3.   
  4. int main(int argc, char **argv) {  
  5.     if ( argc != 2 && argc != 3 ) {  
  6.         printf("Usage: %s stock_code [end_point]/n", argv[0]);  
  7.         exit(-1);  
  8.     }  
  9.   
  10.     struct soap soap;  
  11.     soap_init(&soap);  
  12.     soap_set_mode(&soap, SOAP_C_UTFSTRING);  
  13.     struct _ns1__getStockInfoByCode request;  
  14.     struct _ns1__getStockInfoByCodeResponse response;  
  15.   
  16.     request.theStockCode = argv[1];  
  17.     char *endpoint = NULL;  
  18.     if ( argc == 3 )  
  19.         endpoint = argv[2];  
  20.     if ( soap_call___ns3__getStockInfoByCode(&soap, endpoint, NULL, &request, &response) == SOAP_OK ) {  
  21.         int element_counter = response.getStockInfoByCodeResult->__sizestring;  
  22.         int i = 0;  
  23.         for ( i = 0; i < element_counter; i++ ) {  
  24.             switch ( i ) {  
  25.                 case 0  : printf("Stock code        : "); break;  
  26.                 case 1  : printf("Stock name        : "); break;  
  27.                 case 2  : printf("Timestamp         : "); break;  
  28.                 case 3  : printf("Latest price      : "); break;  
  29.                 case 4  : printf("Closing price T-1 : "); break;  
  30.                 case 5  : printf("Opening price     : "); break;  
  31.                 case 6  : printf("Ups and downs     : "); break;  
  32.                 case 7  : printf("Mininum price     : "); break;  
  33.                 case 8  : printf("Maxinum price     : "); break;  
  34.                 case 9  : printf("Amount of up/down : "); break;  
  35.                 case 10 : printf("Trading volume    : "); break;  
  36.                 case 11 : printf("Trading amount    : "); break;  
  37.                 case 12 : printf("Buy price         : "); break;  
  38.                 case 13 : printf("Sell price        : "); break;  
  39.                 case 14 : printf("Agency trans      : "); break;  
  40.                 case 15 : printf("Buy  1            : "); break;  
  41.                 case 16 : printf("Buy  2            : "); break;  
  42.                 case 17 : printf("Buy  3            : "); break;  
  43.                 case 18 : printf("Buy  4            : "); break;  
  44.                 case 19 : printf("Buy  5            : "); break;  
  45.                 case 20 : printf("Sell 1            : "); break;  
  46.                 case 21 : printf("Sell 2            : "); break;  
  47.                 case 22 : printf("Sell 3            : "); break;  
  48.                 case 23 : printf("Sell 4            : "); break;  
  49.                 case 24 : printf("Sell 5            : "); break;  
  50.                 default : break;  
  51.             }  
  52.             printf("%s/n", response.getStockInfoByCodeResult->string[i]);  
  53.         }  
  54.     }  
  55.     else {  
  56.         soap_print_fault(&soap, stderr);  
  57.     }  
  58.   
  59.     soap_destroy(&soap);  
  60.     soap_end(&soap);  
  61.     soap_done(&soap);  
  62.     return 0;  
  63. }  

 

使服务端程序在某一高位端口下运行,比如

-bash-3.2$ ./stock_server 6883

Socket connect successfully: master socket = 3

 

另起一个窗口执行客户端程序,并且指定end point

-bash-3.2$ ./stock sh600000 http://localhost:6883

Stock code        : sh600000

Stock name        : sh600000

Timestamp         : sh600000

Latest price      : sh600000

Closing price T-1 : sh600000

Opening price     : sh600000

Ups and downs     : sh600000

Mininum price     : sh600000

Maxinum price     : sh600000

Amount of up/down : sh600000

Trading volume    : sh600000

Trading amount    : sh600000

Buy price         : sh600000

Sell price        : sh600000

Agency trans      : sh600000

Buy  1            : sh600000

Buy  2            : sh600000

Buy  3            : sh600000

Buy  4            : sh600000

Buy  5            : sh600000

Sell 1            : sh600000

Sell 2            : sh600000

Sell 3            : sh600000

Sell 4            : sh600000

Sell 5            : sh600000

 

成功!


你可能感兴趣的:(使用gSOAP开发实例(2) 股票信息服务端程序)