日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

gsoap使用心得!

發(fā)布時(shí)間:2023/12/9 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 gsoap使用心得! 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

From: http://www.cppblog.com/qiujian5628/archive/2008/06/19/54019.html


完整源碼下載

最近換了個(gè)工作環(huán)境,現(xiàn)在在大望路這邊上班,呵,剛上班接到的任務(wù)就是熟悉gsoap!廢話(huà)少說(shuō),現(xiàn)在開(kāi)始gSoap學(xué)習(xí)!

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

下載地址:http://sourceforge.net/projects/gsoap2

官方網(wǎng)站:http://genivia.com/Products/gsoap/index.html

對(duì)于Windows平臺(tái)下開(kāi)發(fā)客戶(hù)端,首先下載最新的gsoap_win32_2.7.6c.zip包,具體在以下地址:http://optusnet.dl.sourceforge.net/sourceforge/gsoap2/gsoap_win32_2.7.6c.zip

首先查看gsoap的User's Guide,基本就能對(duì)gsoap有個(gè)全面的了解,通過(guò)閱讀Sample里的例子程序深入。然后搜索網(wǎng)上其它一些文章,比如:
gSOAP簡(jiǎn)單多線(xiàn)程服務(wù)器程序 http://blog.chinaunix.net/u1/55091/showart_430965.html
純c gSoap實(shí)現(xiàn)WebService??????????? http://hi.baidu.com/2sky2sea/blog/item/40ec5555680279c1b745ae9b.html?


接下來(lái)我結(jié)合自己的實(shí)踐與理解,講講VC用gsoap下編寫(xiě)webService和客戶(hù)端程序,有不對(duì)的地方還請(qǐng)大家指正,謝謝。
我以網(wǎng)上出現(xiàn)的實(shí)現(xiàn)一個(gè)簡(jiǎn)單的加法函數(shù)為例,講講我在操作過(guò)程中遇到的問(wèn)題。

一 服務(wù)器端
1.首先編寫(xiě) add.h文件:
1//gsoap?ns?service?name:?add
2//gsoap?ns?service?namespace:?http://localhost/add.wsdl
3//gsoap?ns?service?location:?http://localhost
4//gsoap?ns?service?executable:?add.cgi
5//gsoap?ns?service?encoding:?encoded
6//gsoap?ns?schema?namespace:?urn:add
7
8int?ns__add(?int?num1,?int?num2,?int*?sum?);
9
2.用gsoap/bin目錄下的soapcpp2.exe程序,生成一些文件。可以把soapcpp2.exe拷貝到一add.h目錄下,用cmd執(zhí)行soapcpp2.exe add.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"

int?main(int?argc,?char*?argv[])
{
????
????
int?m,?s;?/*?master?and?slave?sockets?*/
????
struct?soap?add_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,?
"Socket?connection?successful:?master?socket?=?%d\n",?m);
????????
for?(?;?;?)
????????
{?
????????????s?
=?soap_accept(&add_soap);?
????????????
if?(s?<?0)
????????????
{?
????????????????soap_print_fault(
&add_soap,?stderr);
????????????????exit(
-1);
????????????}

????????????fprintf(stderr,?
"Socket?connection?successful:?slave?socket?=?%d\n",?s);
????????????
????????????soap_serve(
&add_soap);//該句說(shuō)明該server的服務(wù)
????????????soap_end(&add_soap);
????????}

????}

????
return?0;
}

//server端的實(shí)現(xiàn)函數(shù)與add.h中聲明的函數(shù)相同,但是多了一個(gè)當(dāng)前的soap連接的參數(shù)
int?ns__add(struct?soap?*add_soap,?int?num1,?int?num2,?int?*sum)
{
????
*sum?=?num1?+?num2;
????
return?0;
}


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)的客戶(hù)端
1。客戶(hù)端程序代碼如下:
#include?<stdio.h>
#include?
<stdlib.h>
#include?
"soapH.h"
#include?
"add.nsmap"


int?add(const?char*?server,?int?num1,?int?num2,?int?*sum);

int?main(int?argc,?char?**argv)?
{
????
int?result?=?-1;
????
char*?server="http://localhost:4567";
????
int?num1?=?0;
????
int?num2?=?0;
????
int?sum?=?0;
????
if(?argc?<?3?)
????
{
????????printf(
"usage:?%s?num1?num2?\n",?argv[0]);
????????exit(
0);
????}

????
????num1?
=?atoi(argv[1]);
????num2?
=?atoi(argv[2]);
????
????result?
=?add(server,?num1,?num2,?&sum);
????
if?(result?!=?0)
????
{
????????printf(
"soap?err,errcode?=?%d\n",?result);
????}

????
else
????
{
????????printf(
"%d+%d=%d\n",?num1,?num2,?sum?);
????}

????
return?0;
}


int?add(?const?char*?server,?int?num1,?int?num2,?int?*sum?)
{
????
struct?soap?add_soap;
????
int?result?=?0;
????soap_init(
&add_soap);
//????soap_set_namespaces(&add_soap,?add_namespaces);
????
????
//該函數(shù)是客戶(hù)端調(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(
"soap?error:%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);
????
return?result;
}

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

三 遇到的問(wèn)題
1.server端可以編譯成CGI方式執(zhí)行,而并不是綁定到某個(gè)端口,這種方式我沒(méi)有實(shí)踐。
if?(argc?<?2)?//?no?args:?assume?this?is?a?CGI?application?
???{?
??????soap_serve(
&soap);?//?serve?request,?one?thread,?CGI?style?
??????soap_destroy(&soap);?//?dealloc?C++?data?
??????soap_end(&soap);?//?dealloc?data?and?clean?up?
}
2.在編譯服務(wù)器及客戶(hù)端程序時(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.多線(xiàn)程方式,在windows下建議用pthread_win32庫(kù),這里給出多線(xiàn)程下的例子。
一?gSOAP需要的頭文件:

// gsoap?ns?service?name:?calc
// gsoap?ns?service?style:?rpc
// gsoap?ns?service?encoding:?encoded
// gsoap?ns?service?namespace:? http://127.0.0.1 :8089/calc.wsdl
// gsoap?ns?service?location:? http://127.0.0.1 :8089/cal
// gsoap?ns?schema??namespace:????urn:calc
int ?ns__add( double ?a,? double ?b,? double ? * result);
int ?ns__sub( double ?a,? double ?b,? double ? * result);
int ?ns__mul( double ?a,? double ?b,? double ? * result);
int ?ns__div( double ?a,? double ?b,? double ? * result);
int ?ns__pow( double ?a,? double ?b,? double ? * result);

二?多線(xiàn)程服務(wù)器關(guān)鍵代碼

#include?
#include??
" calc.nsmap "
#include??
" soapH.h "

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

#define ??BACKLOG?(100)??
#define ??MAX_THR?(10)???
#define ??MAX_QUEUE?(1000)


pthread_mutex_t?queue_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 ? * );???????? // 線(xiàn)程入口函數(shù)
int ?????????enqueue(SOAP_SOCKET);?? // 入隊(duì)列函數(shù)
SOAP_SOCKET?dequeue( void );????????? // 出隊(duì)列函數(shù)

//
// 線(xiàn)程入口函數(shù)
void ? * ?process_queue( void ? * ?soap)
{
??
struct?soap?*?tsoap?=?(struct?soap?*)soap;
??
for(;;)
??
{
????????tsoap
->socket?=?dequeue();
????????
if?(!soap_valid_socket(tsoap->socket))
???????
{
?????????
break;
????????}

????????soap_serve(tsoap);
????????soap_destroy(tsoap);
????????soap_end(tsoap);
??}

??
return?NULL;
}


// 入隊(duì)列操作
int ?enqueue(SOAP_SOCKET?sock)
{
??
int?status?=?SOAP_OK;
??
int?next;
??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);
??
return?status;
}


// 出隊(duì)列操作
SOAP_SOCKET?dequeue()
{
??SOAP_SOCKET?sock;
??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);
??
return?sock;
}



//具體服務(wù)方法////
// 加法的實(shí)現(xiàn)
int ?ns__add( struct ?soap? * soap,? double ?a,? double ?b,? double ? * result)
{
??????
*result?=?a?+?b;
??????
return?SOAP_OK;
}
?
// 減法的實(shí)現(xiàn)
int ?ns__sub( struct ?soap? * soap,? double ?a,? double ?b,? double ? * result)
{?
?????
*result?=?a?-?b;
?????
return?SOAP_OK;
}
?
// 乘法的實(shí)現(xiàn)
int ?ns__mul( struct ?soap? * soap,? double ?a,? double ?b,? double ? * result)
{?
?????
*result?=?a?*?b;
?????
return?SOAP_OK;
}
?
// 除法的實(shí)現(xiàn)
int ?ns__div( struct ?soap? * soap,? double ?a,? double ?b,? double ? * result)
{?
???
if?(b)
???????
*result?=?a?/?b;
???
else
??
{
?????????
char?*s?=?(char*)soap_malloc(soap,?1024);
?????????sprintf(s,?
"Can't">http://tempuri.org/">Can't?divide?%f?by?%f",?a,?b);
?????????return?soap_sender_fault(soap,?"Division?by?zero",?s);
??}

??
return?SOAP_OK;
}
?
// 乘方的實(shí)現(xiàn)
int ?ns__pow( struct ?soap? * soap,? double ?a,? double ?b,? 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't?take?the?power?of?%f?to??%f",?a,?b);
????sprintf(s,?
"Can't">http://tempuri.org/">Can't?take?power?of?%f?to?%f",?a,?b);
????return?soap_sender_fault(soap,?"Power?function?domain?error",?s);
??}

??
return?SOAP_OK;
}
?

//
// 主函數(shù)
int ?main( int ?argc, char ? ** ?argv)
{
??
struct?soap?ServerSoap;
?????
//初始話(huà)運(yùn)行時(shí)環(huán)境
????soap_init(&ServerSoap);
????
//如果沒(méi)有參數(shù),當(dāng)作CGI程序處理
????if?(argc?<2)?
????
{???????
???????????
//CGI?風(fēng)格服務(wù)請(qǐng)求,單線(xiàn)程
??????????soap_serve(&ServerSoap);
??????????
//清除序列化的類(lèi)的實(shí)例
?????????soap_destroy(&ServerSoap);
?????????
//清除序列化的數(shù)據(jù)
????????soap_end(&ServerSoap);?????
???}
else
???
{
?????
struct?soap?*?soap_thr[MAX_THR];
?????pthread_t?tid[MAX_THR];
?????
int?i,port?=?atoi(argv[1]);
?????SOAP_SOCKET?m,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,
"Bind?port?error!?");
????????????????m?
=?soap_bind(&ServerSoap,NULL,port,BACKLOG);
????}

????fprintf(stderr,
"socket?connection?successful?%d?",m);
????????????????
?????
//生成服務(wù)線(xiàn)程
????for(i?=?0;?i?<MAX_THR;?i++)

???
{
??????soap_thr[i]?
=?soap_copy(&ServerSoap);
??????fprintf(stderr,
"Starting?thread?%d?",i);
??????pthread_create(
&tid[i],NULL,(void*(*)(void*))process_queue,(void*)soap_thr[i]);
????}

????????????????
????
for(;;)
????
{
??????
//接受客戶(hù)端的連接
??????s?=?soap_accept(&ServerSoap);
??????
if?(!soap_valid_socket(s))?
??????
{
????????
if?(ServerSoap.errnum)?
????????????????????????????????
{
??????????soap_print_fault(
&ServerSoap,stderr);
??????????
continue;
????????}
else
????????
{
??????????fprintf(stderr,
"Server?timed?out?");
??????????
break;
????????}

??????}

???????
//客戶(hù)端的IP地址
??????fprintf(stderr,"Accepted?connection?from?IP=?%d.%d.%d.%d?socket?=?%d?",
???????????????????????????????((ServerSoap.ip)
>>24)&0xFF,((ServerSoap.ip)>>16)&0xFF,((ServerSoap.ip)>>8)&0xFF,(ServerSoap.ip)&0xFF,(ServerSoap.socket));
??????
//請(qǐng)求的套接字進(jìn)入隊(duì)列,如果隊(duì)列已滿(mǎn)則循環(huán)等待
???????while(enqueue(s)?==?SOAP_EOM)
????????????????Sleep(
1000);
????}

????
//服務(wù)結(jié)束后的清理工作
????for(i?=?0;?i?<?MAX_THR;?i++)
????
{
??????
while?(enqueue(SOAP_INVALID_SOCKET)?==?SOAP_EOM)?
???????
{
???????????Sleep(
1000);
??????}

????}

????
for(i=0;?i<?MAX_THR;?i++)
????
{
??????fprintf(stderr,
"Waiting?for?thread?%d?to?terminate?..",i);
??????pthread_join(tid[i],NULL);
??????fprintf(stderr,
"terminated?");
??????soap_done(soap_thr[i]);
??????free(soap_thr[i]);
????}

????pthread_mutex_destroy(
&queue_cs);
????pthread_cond_destroy(
&queue_cv);
??}

????
//分離運(yùn)行時(shí)的環(huán)境
??soap_done(&ServerSoap);
??
return?0;
}


總結(jié)

以上是生活随笔為你收集整理的gsoap使用心得!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。