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

电信provisioning系统中,常常需要与远程服务器实时交换一些数据,以完成用户的请求。由于简单对象访问协议(Simple Object Access Protocol, SOAP)的流行,许多涉及到第三方的应用,我们一般都比较乐意使用SOAP来开发。不过,由于可能涉及到公司的机密,本系列教程的开发实例尽量采用在网上已经公开的Web Service资源。
 
上文已经交待了gSOAPLinux环境下的编译方法和客户端的实例程序,本文继续讲解其服务端程序的开发。由于不可能获得真正的数据库内容,我们设定的目标是,所有返回的内容都是客户端传入的股票代码。
 
首先,在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
 
服务端的主程序稍微比客户端复杂些,因为还要处理客户端的其他请求,至少要有其函数体,否则编译时会报错。

#include  " soapH.h "
#include 
" ChinaStockWebServiceSoap12.nsmap "

int  main( int  argc,  char   ** argv) {
    
if  ( argc  !=   2  ) {
        printf(
" Usage: %s port\n " , argv[ 0 ]);
        exit(
- 1 );
    }
    
int  port  =  atol(argv[ 1 ]);

    
struct  soap soap;
    soap_init(
& soap);
    
int  m, s;
    
if  ( (m  =  soap_bind( & soap, NULL, port,  100 ))  <   0  ) {
        soap_print_fault(
& soap, stderr);
    }
    
else  {
        printf(
" Socket connect successfully: master socket = %d\n " , m);
        
int  i  =   0 ;
        
while  (  1  ) {
            
if  ( (s  =  soap_accept( & soap))  <   0  ) {
                soap_print_fault(
& soap, stderr);
                
break ;
            }
            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);
            
if  ( soap_serve( & soap)  !=  SOAP_OK ) {
                soap_print_fault(
& soap, stderr);
                
break ;
            }
            soap_end(
& soap);
        }
    }
    soap_done(
& soap);
}

int  __ns3__getStockInfoByCode(
    
struct  soap  * soap,
    
struct  _ns1__getStockInfoByCode  * request,
    
struct  _ns1__getStockInfoByCodeResponse  * response) {
    
int  element_counter  =   25 ;
    response
-> getStockInfoByCodeResult  =  ( struct  ns1__ArrayOfString  * ) malloc( sizeof ( struct  ns1__ArrayOfString));
    response
-> getStockInfoByCodeResult -> __sizestring  =  element_counter;
    response
-> getStockInfoByCodeResult -> string   =  ( char   ** ) malloc( sizeof ( char   * *  element_counter);
    
int  i  =   0 ;
    
for  ( i  =   0 ; i  <  element_counter; i ++  ) {
        response
-> getStockInfoByCodeResult -> string [i]  =  ( char   * ) malloc( sizeof ( char *   32 );
        strcpy(response
-> getStockInfoByCodeResult -> string [i], request -> theStockCode);
    }
    
return  SOAP_OK;
}

int  __ns3__getStockImage_USCOREkByteByCode(
    
struct  soap  * soap,
    
struct  _ns1__getStockImage_USCOREkByteByCode  * request,
    
struct  _ns1__getStockImage_USCOREkByteByCodeResponse  * response) {
    
return  SOAP_OK;
}

int  __ns3__getStockImage_USCOREkByCode(
    
struct  soap  * soap,
    
struct  _ns1__getStockImage_USCOREkByCode  * request,
    
struct  _ns1__getStockImage_USCOREkByCodeResponse  * response) {
    
return  SOAP_OK;
}

int  __ns3__getStockImageByteByCode(
    
struct  soap  * soap,
    
struct  _ns1__getStockImageByteByCode  * request,
    
struct  _ns1__getStockImageByteByCodeResponse  * response) {
    
return  SOAP_OK;
}

int  __ns3__getStockImageByCode(
    
struct  soap  * soap,
    
struct  _ns1__getStockImageByCode  * request,
    
struct  _ns1__getStockImageByCodeResponse  * response) {
    
return  SOAP_OK;
}

int  __ns2__getStockInfoByCode(
    
struct  soap  * soap,
    
struct  _ns1__getStockInfoByCode  * request,
    
struct  _ns1__getStockInfoByCodeResponse  * response) {
    
int  element_counter  =   25 ;
    response
-> getStockInfoByCodeResult  =  ( struct  ns1__ArrayOfString  * ) malloc( sizeof ( struct  ns1__ArrayOfString));
    response
-> getStockInfoByCodeResult -> __sizestring  =  element_counter;
    response
-> getStockInfoByCodeResult -> string   =  ( char   ** ) malloc( sizeof ( char   * *  element_counter);
    
int  i  =   0 ;
    
for  ( i  =   0 ; i  <  element_counter; i ++  ) {
        response
-> getStockInfoByCodeResult -> string [i]  =  ( char   * ) malloc( sizeof ( char *   32 );
        strcpy(response
-> getStockInfoByCodeResult -> string [i], request -> theStockCode);
    }
    
return  SOAP_OK;
}

int  __ns2__getStockImage_USCOREkByteByCode(
    
struct  soap  * soap,
    
struct  _ns1__getStockImage_USCOREkByteByCode  * request,
    
struct  _ns1__getStockImage_USCOREkByteByCodeResponse  * response) {
    
return  SOAP_OK;
}

int  __ns2__getStockImage_USCOREkByCode(
    
struct  soap  * soap,
    
struct  _ns1__getStockImage_USCOREkByCode  * request,
    
struct  _ns1__getStockImage_USCOREkByCodeResponse  * response) {
    
return  SOAP_OK;
}

int  __ns2__getStockImageByteByCode(
    
struct  soap  * soap,
    
struct  _ns1__getStockImageByteByCode  * request,
    
struct  _ns1__getStockImageByteByCodeResponse  * response) {
    
return  SOAP_OK;
}

int  __ns2__getStockImageByCode(
    
struct  soap  * soap,
    
struct  _ns1__getStockImageByCode  * request,
    
struct  _ns1__getStockImageByCodeResponse  * response) {
    
return  SOAP_OK;
}


值得注意的是,如果项目中存在多个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

#include  " soapH.h "
#include 
" ChinaStockWebServiceSoap12.nsmap "

int  main( int  argc,  char   ** argv) {
    
if  ( argc  !=   2   &&  argc  !=   3  ) {
        printf(
" Usage: %s stock_code [end_point]\n " , argv[ 0 ]);
        exit(
- 1 );
    }

    
struct  soap soap;
    soap_init(
& soap);
    soap_set_mode(
& soap, SOAP_C_UTFSTRING);
    
struct  _ns1__getStockInfoByCode request;
    
struct  _ns1__getStockInfoByCodeResponse response;

    request.theStockCode 
=  argv[ 1 ];
    
char   * endpoint  =  NULL;
    
if  ( argc  ==   3  )
        endpoint 
=  argv[ 2 ];
    
if  ( soap_call___ns3__getStockInfoByCode( & soap, endpoint, NULL,  & request,  & response)  ==  SOAP_OK ) {
        
int  element_counter  =  response.getStockInfoByCodeResult -> __sizestring;
        
int  i  =   0 ;
        
for  ( i  =   0 ; i  <  element_counter; i ++  ) {
            
switch  ( i ) {
                
case   0   : printf( " Stock code        :  " );  break ;
                
case   1   : printf( " Stock name        :  " );  break ;
                
case   2   : printf( " Timestamp         :  " );  break ;
                
case   3   : printf( " Latest price      :  " );  break ;
                
case   4   : printf( " Closing price T-1 :  " );  break ;
                
case   5   : printf( " Opening price     :  " );  break ;
                
case   6   : printf( " Ups and downs     :  " );  break ;
                
case   7   : printf( " Mininum price     :  " );  break ;
                
case   8   : printf( " Maxinum price     :  " );  break ;
                
case   9   : printf( " Amount of up/down :  " );  break ;
                
case   10  : printf( " Trading volume    :  " );  break ;
                
case   11  : printf( " Trading amount    :  " );  break ;
                
case   12  : printf( " Buy price         :  " );  break ;
                
case   13  : printf( " Sell price        :  " );  break ;
                
case   14  : printf( " Agency trans      :  " );  break ;
                
case   15  : printf( " Buy  1            :  " );  break ;
                
case   16  : printf( " Buy  2            :  " );  break ;
                
case   17  : printf( " Buy  3            :  " );  break ;
                
case   18  : printf( " Buy  4            :  " );  break ;
                
case   19  : printf( " Buy  5            :  " );  break ;
                
case   20  : printf( " Sell 1            :  " );  break ;
                
case   21  : printf( " Sell 2            :  " );  break ;
                
case   22  : printf( " Sell 3            :  " );  break ;
                
case   23  : printf( " Sell 4            :  " );  break ;
                
case   24  : printf( " Sell 5            :  " );  break ;
                
default  :  break ;
            }
            printf(
" %s\n " , response.getStockInfoByCodeResult -> string [i]);
        }
    }
    
else  {
        soap_print_fault(
& soap, stderr);
    }

    soap_destroy(
& soap);
    soap_end(
& soap);
    soap_done(
& soap);
    
return   0 ;
}


使服务端程序在某一高位端口下运行,比如
-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) 股票信息服务端程序)