gsoap使用總結

來源:互聯網
上載者:User

標籤:des   blog   http   使用   os   strong   檔案   資料   

>>用C實現WebService,gsoap是最好的選擇了。近一個月都在折騰這個,做個總結吧,估計會寫得比較長。因為其中碰到了不少問題,但最終都解決調了。
>>快速開始
  1. gsoap官網。遇到問題時,官網往往是最能提供協助的地方。
     http://gsoap2.sourceforge.net/
  2. 幾個值得參考的連結。
     GSoap使用心得: http://www.cppblog.com/qiujian5628/archive/2008/10/11/54019.html
     GSoap介面定義: http://blog.sina.com.cn/s/blog_5ee9235c0100de3g.html
    
>>測試代碼。
  我是在linux下用C開發的,那就Makefile入手吧。至於服務端的代碼,和用戶端的代碼,可以參考《GSoap使用心得》,或者是gsoap內建的例子。
     a. 用soapcpp2生產gsoap相關代碼: $(GSOAP_BIN)/soapcpp2 -c -x ${WSNAME}.h
     b. 服務端所需的代碼: soapC.c soapServer.c stdsoap2.c
     c. 用戶端所需的代碼: soapC.c soapClient.c stdsoap2.c
     d. 其中stdsoap2.c是從gsoap開發包中複製過來的,他的檔案是(a)中命令產生的。
    
-------------分隔字元------------------------------------
GSOAP_BIN=/usr/local/gSOAP/bin
WSNAME0=soap
WSNAME=SmsWBS
SERVER_OBJS=$(WSNAME0)C.o $(WSNAME0)Server.o stdsoap2.o    ${WSNAME}server.o
CLIENT_OBJS=$(WSNAME0)C.o $(WSNAME0)Client.o stdsoap2.o    ${WSNAME}client.o
AA_OBJS=$(WSNAME0)C.o $(WSNAME0)Server.o $(WSNAME0)Client.o stdsoap2.o ${WSNAME}server.o ${WSNAME}client.o

INCLUDE=
LIBS=
CC=g++ -g -DWITH_NONAMESPACES

#LIBS=-lz -lc -lncurses -lssl -lcrypto
#CC=g++ -g -DWITH_NONAMESPACES -DWITH_OPENSSL

all:server
all:client


${WSNAME}.wsdl:${WSNAME}.h
    $(GSOAP_BIN)/soapcpp2 -c -x ${WSNAME}.h

$(AA_OBJS):%.o:%.c
    $(CC) -c $? $(INCLUDE)

server:Makefile ${WSNAME}.wsdl  $(SERVER_OBJS)
    $(CC) $(SERVER_OBJS) $(LIBS) -o Smsserver -lpthread

client:Makefile ${WSNAME}.wsdl  $(CLIENT_OBJS)
    $(CC) $(CLIENT_OBJS) $(LIBS) -o Smsclient

clean:
    rm -f *.o *.xml *.a *.wsdl *.nsmap \
    $(WSNAME0)H.h $(WSNAME0)C.c $(WSNAME0)Server.c $(WSNAME0)Client.c \
    $(WSNAME0)Stub.* $(WSNAME)$(WSNAME)Proxy.* $(WSNAME)$(WSNAME)Object.* \
    $(WSNAME0)ServerLib.c $(WSNAME0)ClientLib.c $(WSNAME)server ns.xsd $(WSNAME)test

clear:
    rm -f *.o ns.xsd
-------------分隔字元------------------------------------


>>介面定義,可參考《GSoap介面定義》。這裡我將給出C#引用這個webserver所對應的介面形式。
  gsoap是根據我們定義好的.h檔案,然後用工具產生了我們所需的.c檔案。所以我們必鬚根據gsoap的要求編寫.h。
  1. 單個參數的傳出:
     int ns__add( int a, int b, int *c );
     需要說明的是,這裡的ns__是必須的,必須以開始注釋中的ns加兩個底線開始。傳回值必須是int。
     但是這裡的int並不是介面的傳回值,而是gsoap內部的傳回值。真正的傳回值是int *c。
    
     C#中對應的介面:  int add( int a, int b );  傳回值就是上述的int *c參數。
    
  2. 多個參數傳出,在介面中必須使用結構體
     typedef char * xsd__string;
     typedef long   xsd__int;
     struct ns__personResponse{
         xsd__int age;
         xsd__string name;
         xsd__string address;
     };
     int ns__person( xsd__string buf_in, struct ns__personResponse * buf_out );
    
     在C#中,並不是我們所聲明的這樣。而是:int person( string buf_in, out string name, out string address );
     即,結構體中的第一個域會變成傳回值,其他的變成一個個的輸出參數。
    
  3. 返回結構體。如果要返回結構圖,那麼必須在結構體中再套一層結構體:
     typedef char * xsd__string;
     typedef long   xsd__int;
     struct ns__person{
         xsd__int age;
         xsd__string name;
         xsd__string address;    
     };
     struct ns__personResponse{
         xsd__int ret;
         struct ns__person person;
     };
     int ns__person( xsd__string buf_in, struct ns__personResponse * buf_out );
    
     那麼在C#中,看到的介面是這樣的:int person( string buf_in, person對應的結構類 );
    
  4. 介面中的底線,如果介面中的交易名有底線,必須這麼聲明:
     int ns__echo_USCOREreverse( char * buf_in, char ** buf_out );
    
     那麼,C#中實際上的介面名就是:string echo_reverse( string buf_in );

  
>>gsoap中返回字串
  1. 下面是一個逆轉字串的函數。
     int ns__echo_USCOREreverse( char * buf_in, char ** buf_out );
     int ns__echo_USCOREreverse( struct soap *add_soap, char *buf_in, char **buf_out )
     {
        int i, j, len;
        printf( "ns__interface: in=[%s]\n", buf_in );
   
        len = strlen(buf_in);
        *buf_out = (char*)soap_malloc( add_soap, len+1 );
        for( i=len-1, j=0; i>=0; i--, j++ ){
            (*buf_out)[j] = buf_in[i];
        }
        (*buf_out)[j] = 0;

        return 0;
     }
    
     其中調用soap_malloc申請空間,並且將他賦給返回參數buf_out。這個空間會在調用soap_end時被釋放。
    
>>gsoap傳輸中文。我使用utf-8編碼格式來支援漢字的傳輸。
  1. 設定gsoap為utf-8傳輸資料
     soap_set_mode( &SmsWBS_soap, SOAP_C_UTFSTRING );    //設定編碼
     SmsWBS_soap.mode|=SOAP_C_UTFSTRING;
    
  2. 使用下面得函數轉換我們的傳輸內容,即將我們的資料轉成UTF-8編碼:
     int conv_charset( const char *dest, const char *src, char *input, size_t ilen, char *output, size_t olen )
     {
         int convlen = olen;
         iconv_t conv = iconv_open( dest, src );
         if( conv == (iconv_t) -1 )
             return -1;
   
          memset( output, 0, olen );
         if( iconv( conv, &input, &ilen, &output, &olen ) ){
             iconv_close(conv);
             return -1;
         }

         iconv_close(conv);
         return convlen-olen;
     }
     例子: conv_charset( "UTF-8", "GBK", "林學任.linxr", strlen("林學任.linxr"),  buf_out->name, 100 );
 
>>webserver發布
  1. 在C#中,可以直接引用一個webserver,但是我們寫得webserver如何能用被其引用呢。其實只要實現gsoap的fget回呼函數即可:
     SmsWBS_soap.fget = http_get;
  2. http_get函數實現
     int http_get(struct soap * soap)
     {
         FILE *fd = NULL;
    
         char *s = strchr( soap->path, ‘?‘ );
         if( !s || strcmp( s, "?wsdl" ) ){
             return SOAP_GET_METHOD;
         }
    
         fd = fopen( "SmsWBS.wsdl", "rb" );
         if (!fd){
             return 404;
         }
    
         soap->http_content = "text/xml";
         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;
             }
         }
    
         fclose(fd);
         soap_end_send(soap);
    
         return SOAP_OK;
     }
    

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.