gSoap開(kāi)發(fā)webservice client實(shí)例及詳解_第1頁(yè)
gSoap開(kāi)發(fā)webservice client實(shí)例及詳解_第2頁(yè)
gSoap開(kāi)發(fā)webservice client實(shí)例及詳解_第3頁(yè)
gSoap開(kāi)發(fā)webservice client實(shí)例及詳解_第4頁(yè)
gSoap開(kāi)發(fā)webservice client實(shí)例及詳解_第5頁(yè)
已閱讀5頁(yè),還剩5頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

gSOAP是一個(gè)夸平臺(tái)的,用于開(kāi)發(fā)WebService服務(wù)端和客戶端的工具,在Windows、Linux、MACOS和UNIX下使用C和C++語(yǔ)言編碼,集合了SSL功能。

下載地址:/projects/gsoap2官方網(wǎng)站:/Products/gsoap/index.html對(duì)于Windows平臺(tái)下開(kāi)發(fā)客戶端,首先下載最新的gsoap_win32_2.7.6c.zip包,具體在以下地址:/sourceforge/gsoap2/gsoap_win32_2.7.6c.zip首先查看gsoap的User'sGuide,基本就能對(duì)gsoap有個(gè)全面的了解,通過(guò)閱讀Sample里的例子程序深入。然后搜索網(wǎng)上其它一些文章,比如:

gSOAP簡(jiǎn)單多線程服務(wù)器程序/u1/55091/showart_430965.html

純cgSoap實(shí)現(xiàn)WebService

/2sky2sea/blog/item/40ec5555680279c1b745ae9b.html

接下來(lái)我結(jié)合自己的實(shí)踐與理解,講講VC用gsoap下編寫(xiě)webService和客戶端程序,有不對(duì)的地方還請(qǐng)大家指正,謝謝。

我以網(wǎng)上出現(xiàn)的實(shí)現(xiàn)一個(gè)簡(jiǎn)單的加法函數(shù)為例,講講我在操作過(guò)程中遇到的問(wèn)題。一服務(wù)器端

1.首先編寫(xiě)add.h文件:

1//gsoapnsservicename:add

2//gsoapnsservicenamespace:

http://localhost/add.wsdl

3//gsoapnsservicelocation:

http://localhost

4//gsoapnsserviceexecutable:add.cgi

5//gsoapnsserviceencoding:encoded

6//gsoapnsschemanamespace:urn:add

7

8intns__add(intnum1,intnum2,int*sum);

9

2.用gsoap/bin目錄下的soapcpp2.exe程序,生成一些文件??梢园裺oapcpp2.exe拷貝到一add.h目錄下,用cmd執(zhí)行soapcpp2.exeadd.h就可以,在這個(gè)目錄下會(huì)自動(dòng)生成許多將來(lái)有用的文件,如add.namap,soapH.h,soapC.cpp,soapClient.cpp,soapServer.cpp等文件。soapcpp2.exe可以帶參數(shù)執(zhí)行,具體執(zhí)行soapcpp2.exe-h查看。3.新建一個(gè)win32控制臺(tái)工程,加入wsock32.lib庫(kù),將剛才生成的那些文件添加到工程中。然后編寫(xiě)webserver.cpp主程序:

#include"add.h"

#include"add.nsmap"intmain(intargc,char*argv[])

{

intm,s;/**//*masterandslavesockets*/

structsoapadd_soap;

soap_init(&add_soap);

//soap_set_namespaces(&add_soap,add_namespaces);

if(argc<2)

{

printf("usage:%s<server_port>/n",argv[0]);

exit(1);

}

else

{

m=soap_bind(&add_soap,NULL,atoi(argv[1]),100);

if(m<0)

{

soap_print_fault(&add_soap,stderr);

exit(-1);

}

fprintf(stderr,"Socketconnectionsuccessful:mastersocket=%d/n",m);

for(;;)

{

s=soap_accept(&add_soap);

if(s<0)

{

soap_print_fault(&add_soap,stderr);

exit(-1);

}

fprintf(stderr,"Socketconnectionsuccessful:slavesocket=%d/n",s);

soap_serve(&add_soap);//該句說(shuō)明該server的服務(wù)

soap_end(&add_soap);

}

}

return0;

}

//server端的實(shí)現(xiàn)函數(shù)與add.h中聲明的函數(shù)相同,但是多了一個(gè)當(dāng)前的soap連接的參數(shù)

intns__add(structsoap*add_soap,intnum1,intnum2,int*sum)

{

*sum=num1+num2;

return0;

}4.編譯這個(gè)程序,會(huì)提示錯(cuò)誤,將gsoap_win32目錄下stdsoap2.cpp,stdsoap2.h文件加入工程,重新編譯如果還有錯(cuò)誤,可能是你將add.h生成的文件添加入工程出錯(cuò)的原因。實(shí)際上在編寫(xiě)server程序時(shí),無(wú)須帶Client的那些文件,還有帶Lib的文件也無(wú)須添加到工程中。再重新編譯應(yīng)該就沒(méi)有問(wèn)題了,啟動(dòng)4567端口,在ie中輸入localhost:4567,如果顯示xml頁(yè)面,說(shuō)明程序已經(jīng)啟動(dòng)。二對(duì)應(yīng)的客戶端

1??蛻舳顺绦虼a如下:

#include<stdio.h>

#include<stdlib.h>

#include"soapH.h"

#include"add.nsmap"

intadd(constchar*server,intnum1,intnum2,int*sum);intmain(intargc,char**argv)

{

intresult=-1;

char*server="http://localhost:4567";

intnum1=0;

intnum2=0;

intsum=0;

if(argc<3)

{

printf("usage:%snum1num2/n",argv[0]);

exit(0);

}

num1=atoi(argv[1]);

num2=atoi(argv[2]);

result=add(server,num1,num2,&sum);

if(result!=0)

{

printf("soaperr,errcode=%d/n",result);

}

else

{

printf("%d+%d=%d/n",num1,num2,sum);

}

return0;

}intadd(constchar*server,intnum1,intnum2,int*sum)

{

structsoapadd_soap;

intresult=0;

soap_init(&add_soap);

//

soap_set_namespaces(&add_soap,add_namespaces);

//該函數(shù)是客戶端調(diào)用的主要函數(shù),后面幾個(gè)參數(shù)和add.h中聲明的一樣,前面多了3個(gè)參數(shù),函數(shù)名是接口函數(shù)名ns__add前面加上soap_call_

soap_call_ns__add(&add_soap,server,"",num1,num2,sum);

if(add_soap.error)

{

printf("soaperror:%d,%s,%s/n",add_soap.error,*soap_faultcode(&add_soap),*soap_faultstring(&add_soap));

result=add_soap.error;

}

soap_end(&add_soap);

soap_done(&add_soap);

returnresult;

}

2.客戶端程序既可以新建一個(gè)新的win32控制臺(tái)程序,將剛才生成的nsmap,soapH.h,soapClient.h等文件加入工程,編譯既可。我是直接在原先工程中加入一客戶端代碼,將webserver.cpp文件移除,并且將soapServer.cpp等server端需要的文件移除,將soapClient.cpp等client端需要的cpp添加到工程,編譯既可。

3.啟動(dòng)server程序,F(xiàn)5客戶端程序,經(jīng)測(cè)試正常。三遇到的問(wèn)題

1.server端可以編譯成CGI方式執(zhí)行,而并不是綁定到某個(gè)端口,這種方式我沒(méi)有實(shí)踐。

if(argc<2)//noargs:assumethisisaCGIapplication

{

soap_serve(&soap);//serverequest,onethread,CGIstyle

soap_destroy(&soap);//deallocC++data

soap_end(&soap);//deallocdataandcleanup

}2.在編譯服務(wù)器及客戶端程序時(shí)一開(kāi)始對(duì)add.h生成的文件添加到工程,經(jīng)常出現(xiàn)問(wèn)題,需要自己不調(diào)試。特別是鏈接時(shí)段,server/client要與其生成的文件相對(duì)應(yīng),server調(diào)用生成的soapserver.cpp,client調(diào)用生成的soapclient.cpp文件。

3.多線程方式,在windows下建議用pthread_win32庫(kù),這里給出多線程下的例子。

一gSOAP需要的頭文件://gsoapnsservicename:calc

//gsoapnsservicestyle:rpc

//gsoapnsserviceencoding:encoded

//gsoapnsservicenamespace:

:8089/calc.wsdl

//gsoapnsservicelocation:

:8089/cal

//gsoapnsschema

namespace:

urn:calc

intns__add(doublea,doubleb,double*result);

intns__sub(doublea,doubleb,double*result);

intns__mul(doublea,doubleb,double*result);

intns__div(doublea,doubleb,double*result);

intns__pow(doublea,doubleb,double*result);二多線程服務(wù)器關(guān)鍵代碼#include

#include

"calc.nsmap"

#include

"soapH.h"/**//////////////////////////////////////////////////////////////////////////

///宏與全局變量的定義

#define

BACKLOG(100)

#define

MAX_THR(10)

#define

MAX_QUEUE(1000)

pthread_mutex_tqueue_cs;

//隊(duì)列鎖

pthread_cond_t

queue_cv;

//條件變量

SOAP_SOCKET

queue[MAX_QUEUE];

//數(shù)組隊(duì)列

int

head=0,tail=0;

//隊(duì)列頭隊(duì)列尾初始化

/**///////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

void*

process_queue(void*);

//線程入口函數(shù)

int

enqueue(SOAP_SOCKET);

//入隊(duì)列函數(shù)

SOAP_SOCKETdequeue(void);

//出隊(duì)列函數(shù)/**///////////////////////////////////////////////////////////////////////////

//線程入口函數(shù)

void*process_queue(void*soap)

{

structsoap*tsoap=(structsoap*)soap;

for(;;)

{

tsoap->socket=dequeue();

if(!soap_valid_socket(tsoap->socket))

{

break;

}

soap_serve(tsoap);

soap_destroy(tsoap);

soap_end(tsoap);

}

returnNULL;

}//入隊(duì)列操作

intenqueue(SOAP_SOCKETsock)

{

intstatus=SOAP_OK;

intnext;

pthread_mutex_lock(&queue_cs);

next=tail+1;

if(next>=MAX_QUEUE)

next=0;

if(next==head)

status=SOAP_EOM;

else

{

queue[tail]=sock;

tail=next;

}

pthread_cond_signal(&queue_cv);

pthread_mutex_unlock(&queue_cs);

returnstatus;

}//出隊(duì)列操作

SOAP_SOCKETdequeue()

{

SOAP_SOCKETsock;

pthread_mutex_lock(&queue_cs);

while(head==tail)

{

pthread_cond_wait(&queue_cv,&queue_cs);

}

sock=queue[head++];

if(head>=MAX_QUEUE)

{

head=0;

}

pthread_mutex_unlock(&queue_cs);

returnsock;

}

/**///////////////////////////具體服務(wù)方法////////////////////////////////////////

//加法的實(shí)現(xiàn)

intns__add(structsoap*soap,doublea,doubleb,double*result)

{

*result=a+b;

returnSOAP_OK;

}

//減法的實(shí)現(xiàn)

intns__sub(structsoap*soap,doublea,doubleb,double*result)

{

*result=a-b;

returnSOAP_OK;

}

//乘法的實(shí)現(xiàn)

intns__mul(structsoap*soap,doublea,doubleb,double*result)

{

*result=a*b;

returnSOAP_OK;

}

//除法的實(shí)現(xiàn)

intns__div(structsoap*soap,doublea,doubleb,double*result)

{

if(b)

*result=a/b;

else

{

char*s=(char*)soap_malloc(soap,1024);

sprintf(s,"Can't">/">Can'tdivide%fby%f",a,b);

returnsoap_sender_fault(soap,"Divisionbyzero",s);

}

returnSOAP_OK;

}

//乘方的實(shí)現(xiàn)

intns__pow(structsoap*soap,doublea,doubleb,double*result)

{

*result=pow(a,b);

if(soap_errno==EDOM)/**//*soap_errno和errorno類(lèi)似,但是和widnows兼容*/

{

char*s=(char*)soap_malloc(soap,1024);

sprintf(s,"Can'ttakethepowerof%fto

%f",a,b);

sprintf(s,"Can't">/">Can'ttakepowerof%fto%f",a,b);

returnsoap_sender_fault(soap,"Powerfunctiondomainerror",s);

}

returnSOAP_OK;

}/**///////////////////////////////////////////////////////////////////////////////////////////////////////

//主函數(shù)

intmain(intargc,char**argv)

{

structsoapServerSoap;

//初始話運(yùn)行時(shí)環(huán)境

soap_init(&ServerSoap);

//如果沒(méi)有參數(shù),當(dāng)作CGI程序處理

if(argc<2)

{

//CGI風(fēng)格服務(wù)請(qǐng)求,單線程

soap_serve(&ServerSoap);

//清除序列化的類(lèi)的實(shí)例

soap_destroy(&ServerSoap);

//清除序列化的數(shù)據(jù)

soap_end(&ServerSoap);

}else

{

structsoap*soap_thr[MAX_THR];

pthread_ttid[MAX_THR];

inti,port=atoi(argv[1]);

SOAP_SOCKETm,s;

//鎖和條件變量初始化

pthread_mutex_init(&queue_cs,NULL);

pthread_cond_init(&queue_cv,NULL);

//綁定服務(wù)端口

m=soap_bind(&ServerSoap,NULL,port,BACKLOG);

//循環(huán)直至服務(wù)套接字合法

while(!soap_valid_socket(m))

{

fprintf(stderr,"Bindporterror!");

m=soap_bind(&ServerSoap,NULL,port,BACKLOG);

}

fprintf(stderr,"socketconnectionsuccessful%d",m);

//生成服務(wù)線程

for(i=0;i<MAX_THR;i++)

{

soap_thr[i]=soap_copy(&ServerSoap);

fprintf(stderr,"Startingthread%d",i);

pthread_create(&tid[i],NULL,(void*(*)(void*))process_queue,(void*)soap_thr[i]);

}

for(;;)

{

//接受客戶端的連接

s=soap_accept(&ServerSoap);

if(!soap_valid_socket(s))

{

if(ServerSoap.errnum)

{

soap_print_fault(&ServerSoap,stderr);

continue;

}else

{

fprintf(stderr,"Servertimedout");

break;

}

}

//客戶端的IP地址

fprintf(stderr,"AcceptedconnectionfromIP=%d.%d.%d.%dsocket=%d",

((ServerSoap.ip)>>24)&&0xFF,((ServerSoap.ip)>>16)&0xFF,((ServerSoap.ip)>>8)&0xFF,(S

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論