青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
數(shù)據(jù)加載中……

gSOAP中文文檔

1、背景

   轉(zhuǎn)貼

 

2  gSOAP文檔翻譯計(jì)劃

 

2.1 gSOAP文檔翻譯計(jì)劃(序)

前一陣子需要在unix c平臺(tái)下創(chuàng)建一個(gè)webservice應(yīng)用。頭痛之余,上網(wǎng)查詢相關(guān)資料,偶然發(fā)現(xiàn)了gSOAP開發(fā)包。于是乎立即下載試用了一下,效果很好。在它的幫助下,我很快完成了webservice應(yīng)用的設(shè)計(jì)開發(fā)工作。今天,心里突然升起一個(gè)念頭:為何不把整個(gè)gSOAP的幫助文檔翻譯一下呢?一來可以方便與其他同仁的交流;二來也可以更好的理解gSOAP的原理與思想。只是此項(xiàng)工程工作浩繁,須懷有革命的大無畏精神尚可完成也。如今唯先寫一序,實(shí)則有督促之意耳。

 

2.2 gSOAP文檔翻譯計(jì)劃(1、介紹)

1.介紹

    gSOAP編譯工具提供了一個(gè)SOAP/XML 關(guān)于C/C++ 語言的實(shí)現(xiàn),從而讓C/C++語言開發(fā)web服務(wù)或客戶端程序的工作變得輕松了很多。絕大多數(shù)的C++web服務(wù)工具包提供一組API函數(shù)類庫(kù)來處理特定的SOAP數(shù)據(jù)結(jié)構(gòu),這樣就使得用戶必須改變程序結(jié)構(gòu)來適應(yīng)相關(guān)的類庫(kù)。與之相反,gSOAP利用編譯器技術(shù)提供了一組透明化的SOAP API,并將與開發(fā)無關(guān)的SOAP實(shí)現(xiàn)細(xì)節(jié)相關(guān)的內(nèi)容對(duì)用戶隱藏起來。gSOAP的編譯器能夠自動(dòng)的將用戶定義的本地化的CC++數(shù)據(jù)類型轉(zhuǎn)變?yōu)榉?span lang="EN-US">XML語法的數(shù)據(jù)結(jié)構(gòu),反之亦然。這樣,只用一組簡(jiǎn)單的API就將用戶從SOAP細(xì)節(jié)實(shí)現(xiàn)工作中解脫了出來,可以專注與應(yīng)用程序邏輯的實(shí)現(xiàn)工作了。gSOAP編譯器可以集成C/C++Fortran代碼(通過一個(gè)FortranC的接口),嵌入式系統(tǒng),其他SOAP程序提供的實(shí)時(shí)軟件的資源和信息;可以跨越多個(gè)操作系統(tǒng),語言環(huán)境以及在防火墻后的不同組織。

 

    gSOAP使編寫web服務(wù)的工作最小化了。gSOAP編譯器生成SOAP的代碼來序列化或反序列化C/C++的數(shù)據(jù)結(jié)構(gòu)。gSOAP包含一個(gè)WSDL生成器,用它來為你的web服務(wù)生成web服務(wù)的解釋。gSOAP的解釋器及導(dǎo)入器可以使用戶不需要分析web服務(wù)的細(xì)節(jié)就可以實(shí)現(xiàn)一個(gè)客戶端或服務(wù)端程序。下面是gSOAP的一些特點(diǎn):

 

l        gSOAP編譯器可以根據(jù)用戶定義的CC++數(shù)據(jù)結(jié)構(gòu)自動(dòng)生成符合SOAP的實(shí)例化代碼。

l        gSOAP支持WSDL 1.1, SOAP 1.1, SOAP 1.2, SOAP RPC 編碼方式以及 literal/document 方式.

l        gSOAP是少數(shù)完全支持SOAP1.1 RPC編碼功能的工具包,包括多維數(shù)組及動(dòng)態(tài)類型。比如,一個(gè)包含一個(gè)基類參數(shù)的遠(yuǎn)程方法可以接收客戶端傳來的子類實(shí)例。子類實(shí)例通過動(dòng)態(tài)綁定技術(shù)來保持一致性。

l        gSOAP 支持 MIME (SwA) DIME 附件包。

l        gSOAP是唯一支持DIME附件傳輸?shù)墓ぞ甙K试S你在保證XML可用性的同時(shí)能夠以最快的方式(流方式)傳遞近乎無大小限制的二進(jìn)制數(shù)據(jù)。

l        gSOAP 支持 SOAP-over-UDP

l        gSOAP 支持 IPv4 and IPv6.

l        gSOAP 支持 Zlib deflate and gzip compression (for HTTP, TCP/IP, and XML file storage)

l        gSOAP 支持 SSL (HTTPS)

l        gSOAP 支持 HTTP/1.0, HTTP/1.1 保持連接, 分塊傳輸及基本驗(yàn)證。

l        gSOAP 支持 SOAP 單向消息。

l        gSOAP 包含一個(gè) WSDL 生成器,便于web服務(wù)的發(fā)布。

l        gSOAP 包含一個(gè)WSDL解析器 (WSDL轉(zhuǎn)換為gSOAP頭文件),可以自動(dòng)化用戶客戶端及服務(wù)端的開發(fā)。

l        生成可以單獨(dú)運(yùn)行的web服務(wù)及客戶端程序。

l        因?yàn)橹恍枰苌賰?nèi)存空間,所以可以運(yùn)行在類似Palm OS, Symbian, Pocket PC的小型設(shè)備中。

l        適用于以CC++開發(fā)的web服務(wù)中。

l        跨平臺(tái):Windows, Unix, Linux, Mac OS X, Pocket PC, Palm OS, Symbian等。

l        支持序列化程序中的本地化C/C++數(shù)據(jù)結(jié)構(gòu)。

l        可以使用輸入和輸出緩沖區(qū)來提高效率,但是不用完全消息緩沖來確定HTTP消息的長(zhǎng)度。取而代之的是一個(gè)三相序列化方法。這樣,像64位編碼的圖像就可以在小內(nèi)存設(shè)備(如PDA)中以DIME附件或其他方式傳輸。

l        支持C++單繼承,動(dòng)態(tài)綁定,重載,指針結(jié)構(gòu)(列表、樹、圖、循環(huán)圖,定長(zhǎng)數(shù)組,動(dòng)態(tài)數(shù)組,枚舉,642進(jìn)制編碼及16進(jìn)制編碼)。

l        不需要重寫現(xiàn)有的C/C++應(yīng)用。但是,不能用unions,指針和空指針來作為遠(yuǎn)程方法調(diào)用參數(shù)的數(shù)據(jù)結(jié)構(gòu)中元素。

l        三相編組:1)分析指針,引用,循環(huán)數(shù)據(jù)結(jié)構(gòu);2)確定HTTP消息長(zhǎng)度;3)將數(shù)據(jù)序列化位SOAP1.1編碼方式或用戶定義的數(shù)據(jù)編碼方式。

l        雙相編組:1SOAP解釋及編碼;2)分解“forward”指針(例如:分解SOAP中的href屬性)。

l        完整可定制的SOAP錯(cuò)誤處理機(jī)制。

l        可定制的SOAP消息頭處理機(jī)制,可以用來保持狀態(tài)信息

 

2.3 gSOAP文檔翻譯計(jì)劃(2、符號(hào)規(guī)定)

懶得翻譯了,因?yàn)橐膊荒茉佻F(xiàn)出原來的版式。后面章節(jié)中分別注明吧。

 

2.4 gSOAP文檔翻譯計(jì)劃(3

     gSOAP2.5版與gSOAP 2.4版(或以前版本)的不同按照WS-I Basic Profile 1.0a的要求,gSOAP2.5及以上版本默認(rèn)使用SOAP RPC文字。這不需要去關(guān)心,因?yàn)?span lang="EN-US">WSDL解析器wsdl2h在你提供一個(gè)WSDL文檔時(shí),會(huì)自動(dòng)注意這些不同點(diǎn)。增加了一個(gè)soapcpp2編譯器的編譯選項(xiàng) -e ,用來保持與gSOAP2.4及以前版本的兼容性。

 

2.5 gSOAP文檔翻譯計(jì)劃(4

gSOAP2.2版與gSOAP 2.1版(或以前版本)的不同如果你是從2.1版升級(jí)到2.2或以后版本,請(qǐng)注意這些變化。為了能夠分離傳輸、內(nèi)容編碼、映射中的接收/發(fā)送設(shè)置,改變了運(yùn)行時(shí)選項(xiàng)及標(biāo)志。這些標(biāo)志分布再四個(gè)類中:傳輸(IO),內(nèi)容編碼(ENCXML編組(XML)及C/C++數(shù)據(jù)映射。不再提倡使用舊標(biāo)志soap_disable_Xsoap_enable_X(其中,X表示選項(xiàng)名)。具體內(nèi)容請(qǐng)參見9.12節(jié)。

 

2.6 gSOAP文檔翻譯計(jì)劃(5

gSOAP2.x版與gSOAP 1.x版的不同,如果你是從1.x版升級(jí)到2.x版,請(qǐng)注意下面的內(nèi)容。gSOAP2.0及之后的版本是在1.x版基礎(chǔ)上重寫的。gSOAP2.0之后的版本是線程安全的,但之前版本不是。gSOAP2.x版本中的主要文件已經(jīng)重新命名,以便與1.x版區(qū)分。

 

gSOAP 1.X gSOAP 2.X

soapcpp soapcpp2

soapcpp.exe soapcpp2.exe

stdsoap.h stdsoap2.h

stdsoap.c stdsoap2.c

stdsoap.cpp stdsoap2.cpp

 

1.x版升級(jí)到2.x版并不需要進(jìn)行大量的代碼重寫工作。所有2.x版相關(guān)的函數(shù)都定義在stdsoap2.c[pp]文件中,這個(gè)文件是由gSOAP編譯器自動(dòng)生成的。所以,用1.x版開發(fā)的服務(wù)端或客戶端代碼需要進(jìn)行修改以適應(yīng)2.x版中函數(shù)的變化:在2.x版中,所有的gSOAP函數(shù)都增加了一個(gè)參數(shù)用來保存一個(gè)gSOAP運(yùn)行環(huán)境實(shí)例。這個(gè)參數(shù)包括了文件描述,表,緩沖,標(biāo)志位等,它在所有gSOAP函數(shù)中都是第一個(gè)參數(shù)。

 

gSOAP運(yùn)行環(huán)境實(shí)例是一個(gè)struct soap類型的變量。當(dāng)客戶端程序訪問遠(yuǎn)程方法前或當(dāng)服務(wù)端程序能夠接收一個(gè)請(qǐng)求前,必須先將這個(gè)運(yùn)行環(huán)境變量初始化。在2.x版中新增了3個(gè)函數(shù)來負(fù)責(zé)這些事情:

函數(shù)                                       解釋

soap_init(struct soap *soap)               初始化環(huán)境變量(只需執(zhí)行一次)

struct soap *soap_new()                     定義并初始化環(huán)境變量并返回一個(gè)該變量的指針

struct soap *soap_copy(struct soap *soap)   定義一個(gè)環(huán)境變量并從已有的環(huán)境變量中拷貝環(huán)境信息

 

環(huán)境變量定義好后就可以重復(fù)使用而不必再次初始化了。只有當(dāng)線程獨(dú)占訪問時(shí),我們才需要一個(gè)新的環(huán)境變量。例如,下面的代碼分配了一個(gè)用于多個(gè)遠(yuǎn)程方法的環(huán)境變量:

int main()

{

   struct soap soap;

   soap_init(&soap); // 初始化環(huán)境變量

   ...

   soap_call_ns__method1(&soap, ...); // 調(diào)用一個(gè)遠(yuǎn)程方法

   soap_call_ns__method2(&soap, ...); // 調(diào)用另一個(gè)遠(yuǎn)程方法

   soap_end(&soap); // 清除環(huán)境變量

}

 

我們也可以像下面這樣定義環(huán)境變量:

int main()

{

   struct soap *soap;

   soap = soap_new(); // 定義并初始化環(huán)境變量

   if (!soap) // 如果不能定義,退出

   soap_call_ns__method1(soap, ...); // 調(diào)用遠(yuǎn)程函數(shù)

   soap_call_ns__method2(soap, ...); // 調(diào)用另一個(gè)遠(yuǎn)程函數(shù)

   soap_end(soap); // 清除環(huán)境變量

   free(soap); // 釋放環(huán)境變量空間

}

 

服務(wù)端代碼在調(diào)用soap_serve函數(shù)前,需要定義相關(guān)環(huán)境變量:

int main()

{

   struct soap soap;

   soap_init(&soap);

   soap_serve(&soap);

}

或者像下面這樣:

int main()

{

   soap_serve(soap_new());

}

soap_serve函數(shù)用來處理一個(gè)或多個(gè)(當(dāng)允許HTTP keep-alive時(shí),參見18.11節(jié)中的SOAP_IO_KEEPALIVE標(biāo)志)請(qǐng)求。

一個(gè)web服務(wù)可以用多線程技術(shù)來處理請(qǐng)求:

int main()

{

   struct soap soap1, soap2;

   pthread_t tid;

   soap_init(&soap1);

   if (soap_bind(&soap1, host, port, backlog) < 0) exit(1);

   if (soap_accept(&soap1) < 0) exit(1);

   pthread_create(&tid,NULL, (void*(*)(void*))soap_serve, (void*)&soap1);

   soap_init(&soap2);

   soap_call_ns__method(&soap2, ...); // 調(diào)用遠(yuǎn)程方法

   soap_end(&soap2);

   pthread_join(tid, NULL); // 等待線程結(jié)束

   soap_end(&soap1); // 釋放環(huán)境變量

}

在上面的例子中,需要兩個(gè)環(huán)境變量信息。而在1.x版本中,由于靜態(tài)分配環(huán)境變量,多線程技術(shù)是不被允許的(只有一個(gè)線程可以用這個(gè)環(huán)境變量調(diào)用遠(yuǎn)程方法或處理請(qǐng)求信息)。

8.2.4節(jié)將給出一個(gè)具體的多線程服務(wù)實(shí)例,它為每個(gè)SOAP請(qǐng)求分配一個(gè)獨(dú)立線程進(jìn)行處理。

 

2.7 gSOAP文檔翻譯計(jì)劃(6

gSOAP 使用下面的軟件包驗(yàn)證了其可用性: Apache 2.2 Apache Axis ASP.NET Cape Connect Delphi easySOAP++ eSOAP Frontier GLUE IonaXMLBus kSOAP MS SOAP Phalanx SIM SOAP::Lite SOAP4R Spray SQLData Wasp Adv. Wasp C++ White Mesa xSOAP ZSI 4S4C

 

2.8 gSOAP文檔翻譯計(jì)劃(7

準(zhǔn)備工作:

要開始用gSOAP創(chuàng)建一個(gè)web服務(wù)應(yīng)用, 你需要:

 

l        一個(gè)C/C++編譯器.

l        擁有根據(jù)操作系統(tǒng)平臺(tái)創(chuàng)建的可執(zhí)行的gSOAPstdsoap2windows下為stdsoap2.exe)編譯器。

l        擁有根據(jù)操作系統(tǒng)平臺(tái)創(chuàng)建的可執(zhí)行的gSOAPwsdl2hwindows下為wsdl2h.exeWSDL解析器。

l        需要'stdsoap2.c''stdsoap2.cpp''stdsoap2.h'文件來實(shí)現(xiàn)你的SOAP功能。你可以創(chuàng)建一個(gè)dll或動(dòng)態(tài)庫(kù)以便簡(jiǎn)化連接。

l        如果你要支持SSLHTTPS)及壓縮的話,可以安裝OpenSSLZlib庫(kù)。

l        gSOAP是獨(dú)立開發(fā)包,不需要任何第三方的軟件支持(除非你要用到OpenSSLZlib)。

l        與平臺(tái)無關(guān)的gSOAP版本需要你下面的工具編譯'soapcpp2''wsdl2h'文件:

l        一個(gè)C++編譯器(用來編譯'wsdl2h'WSDL解析器)。

l        Bison YaccFlex Lex推薦使用BisonFlex

l        在軟件包samples目錄下有大量的開發(fā)實(shí)例。可以用'make'來編譯這些例子。這些例子包含了gSOAP中的各個(gè)方面。其中,最簡(jiǎn)單的例子是one-linerssamples/oneliners)。

 

2.9 gSOAP文檔翻譯計(jì)劃(8.1.1)快速指南

本指南旨在讓你快速開始你的gSOAP開發(fā)之旅。閱讀本節(jié)的內(nèi)容,需要你對(duì)SOAP 1.1協(xié)議及C/C++語法有大體的了解。雖然使用gSOAP編譯器可以直接用C/C++開始編寫web服務(wù)及客戶端程序而不需要了解SOAP協(xié)議的細(xì)節(jié),但是由于我們?cè)诒竟?jié)中使用了大量的實(shí)例來說明gSOAP與其他SOAP實(shí)現(xiàn)的連接及通訊,所以了解一些SOAPWSDL協(xié)議也是必需的。

 

 

8.1 如何使用gSOAP編譯環(huán)境來編譯SOAP客戶端程序

通常,一個(gè)SOAP客戶端應(yīng)用的實(shí)現(xiàn)需要為每個(gè)客戶端需要調(diào)用的遠(yuǎn)程方法提供一個(gè)存根例程(stub routine)。存根例程主要負(fù)責(zé)編碼參數(shù)信息;將包含參數(shù)信息的調(diào)用請(qǐng)求發(fā)送給制定的SOAP服務(wù);等待返回結(jié)果;將結(jié)果中的參數(shù)信息編碼。客戶端程序調(diào)用訪問遠(yuǎn)程方法的存根例程就像調(diào)用本地方法一樣。用C/C++手工別寫一個(gè)存根例程是個(gè)十分痛苦的差使,尤其當(dāng)遠(yuǎn)程方法的參數(shù)中包含特定的數(shù)據(jù)結(jié)構(gòu)(如:記錄、數(shù)組、圖等)時(shí)。幸運(yùn)的是,gSOAP包中的'wsdl2h'WSDL解析器和'soapcpp2’存根及架構(gòu)編譯器能夠?qū)?span lang="EN-US">web服務(wù)客戶端及服務(wù)端的開發(fā)工作自動(dòng)化。

 

'soapcpp2’存根及架構(gòu)編譯器是可以生成構(gòu)建C++ SOAP客戶端所需的C++源碼的預(yù)編譯器。該預(yù)編譯器的輸入?yún)?shù)是一個(gè)標(biāo)準(zhǔn)的C/C++頭文件。這個(gè)頭文件可以由WSDL解析器根據(jù)相關(guān)的WSDL文檔自動(dòng)生成。

參見下面的命令:

$ wsdl2h -o quote.h http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl

上面的命令根據(jù)制定URL提供的WSDL文檔生成一個(gè)C++語法結(jié)構(gòu)的頭文件。

 

如果需要生成一個(gè)純C的頭文件,需要一下命令:

$ wsdl2h -c -o quote.h http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl

 

更多關(guān)于WSDL解析器及其選項(xiàng)的細(xì)節(jié)信息,請(qǐng)參見8.2.10節(jié)。執(zhí)行上述命令后,quote.h文件就生成了。其中包含開發(fā)客戶端或服務(wù)端程序的存根例程定義。SOAP服務(wù)遠(yuǎn)程方法以函數(shù)聲明的方式在這個(gè)頭文件中被定義。C/C++源代碼的存根例程將通過預(yù)編譯器自動(dòng)實(shí)現(xiàn)。同時(shí),每個(gè)遠(yuǎn)程方法的程序框架也被自動(dòng)生成了,它可以用來建立SOAP服務(wù)端程序應(yīng)用。SOAP服務(wù)的輸入輸出參數(shù)可以是簡(jiǎn)單的數(shù)據(jù)類型或復(fù)雜的數(shù)據(jù)結(jié)構(gòu),可以由WSDL解析器自動(dòng)生成或手工定義。預(yù)編譯器將自動(dòng)生成序列化/反序列化這些數(shù)據(jù)的代碼,以便存根例程可以將這些數(shù)據(jù)以XML的方式編碼或解碼。

 

8.1.1 例子

XMethods Delayed Stock Quote 服務(wù)提供一個(gè)getQuote方法(由'wsdl2h'WSDL解析器生成的quote.h定義)。這個(gè)方法根據(jù)提供的股票名稱返回相應(yīng)的股票價(jià)格。下面是這個(gè)方法的WSDL文檔信息:

 

Endpoint URL: http://services.xmethods.net:80/soap

SOAP action: "" (2 quotes)

Remote method namespace: urn:xmethods-delayed-quotes

Remote method name: getQuote

   Input parameter: symbol of type xsd:string

   Output parameter: Result of type xsd:float

 

 

下面是由WSDL解析器生成的getQuote.h頭文件(實(shí)際的文件內(nèi)容與'wsdl2h'版本及生成選項(xiàng)有關(guān)):

//gSOAP ns1 service name: net_DOTxmethods_DOTservices_DOTstockquote_DOTStockQuoteBinding

//gSOAP ns1 service type: net_DOTxmethods_DOTservices_DOTstockquote_DOTStockQuotePortType

//gSOAP ns1 service port: http://66.28.98.121:9090/soap

//gSOAP ns1 service namespace: urn:xmethods-delayed-quotes

//gSOAP ns1 service documentation: Definitions generated by the gSOAP WSDL parser 1.0

// Service net.xmethods.services.stockquote.StockQuoteService : net.xmethods.services.stockquote.StockQuote web service

//gSOAP ns1 service method-style: getQuote rpc

//gSOAP ns1 service method-encoding: getQuote http://schemas.xmlsoap.org/soap/encoding/

//gSOAP ns1 service method-action: getQuote urn:xmethods-delayed-quotes#getQuote

int ns1__getQuote(char *symbol, float &Result);

 

這個(gè)頭文件用C/C++代碼為gSOAP預(yù)編譯器指定了web服務(wù)的細(xì)節(jié)。遠(yuǎn)程方法被定義為函數(shù)ns1__getQuote,同時(shí)指定了客戶端調(diào)用web服務(wù)所需

的所有細(xì)節(jié)信息。

 

getQuote遠(yuǎn)程方法需要一個(gè)名為symbol的字符串作為輸入?yún)?shù),同時(shí)需要一個(gè)名為Result的浮點(diǎn)數(shù)作為輸出參數(shù)。預(yù)編譯器生成的遠(yuǎn)程方法調(diào)用函數(shù)中,最后一個(gè)參數(shù)必須是輸出參數(shù),該參數(shù)以引用方式傳遞或定義為指針類型。除此之外的所有參數(shù)都是輸入?yún)?shù),這些參數(shù)必須以傳值方式傳遞。函數(shù)返回一個(gè)整型值,其值說明web服務(wù)調(diào)用成功或出現(xiàn)的錯(cuò)誤。具體的錯(cuò)誤代碼信息參見10.2節(jié)。

 

函數(shù)名中命名空間前綴ns1__的細(xì)節(jié)信息將在8.1.2節(jié)中討論。簡(jiǎn)單的說,命名空間前綴與函數(shù)名之間用兩個(gè)下劃線分割。比如,ns1__getQuote中,ns1為命名空間前綴,getQuote是函數(shù)名稱。(函數(shù)名中單個(gè)下劃線將在XML中解釋為破折號(hào)-,因?yàn)樵?span lang="EN-US">XML中破折號(hào)比下劃線更常用,細(xì)節(jié)請(qǐng)參見10.3節(jié))用下面命令執(zhí)行預(yù)編譯器:

 

soapcpp2 getQuote.h

預(yù)編譯器根據(jù)getQuote.h中定義的信息來生成存根例程的代碼框架。這個(gè)存根例程可以在客戶端程序中隨處調(diào)用。存根例程被聲明為下面的樣子:

int soap_call_ns1__getQuote(struct soap *soap, char *URL, char *action, char *symbol, float &Result);

 

存根例程保存在soapClient.cpp文件中;soapC.cpp文件包含了序列化、反序列化數(shù)據(jù)的函數(shù)。你可以用 -c編譯選項(xiàng)來生成純C的代碼。注意,soap_call_ns1__getQuotens1__getQuote的參數(shù)基礎(chǔ)上又增加了三個(gè)參數(shù):soap必須是指向一個(gè)gSOAP運(yùn)行環(huán)境的合法指針;URLweb服務(wù)的URLaction指明了web服務(wù)需要的SOAP actionXMethods Delayed Stock Quote服務(wù)的URLhttp://66.28.98.121:9090/soapaction"" (2 quotes)。你可以動(dòng)態(tài)的改變URLaction。如果上述兩個(gè)變量定義為NULL,則會(huì)使用頭文件中定義的信息。下面的例子調(diào)用遠(yuǎn)程方法獲取IBM的股票信息:

 

#include "soapH.h" // 包含生成的存根例程定義

#include "net_DOT_xmethods_DOT_services_DOT_stockquote_DOT_StockQuoteBinding.nsmap" // 包含命名空間表

int main()

{

   struct soap soap; // gSOAP運(yùn)行環(huán)境

   float quote;

   soap_init(&soap); // 初始化運(yùn)行環(huán)境(只執(zhí)行一次)

   if (soap_call_ns1__getQuote(&soap, NULL, NULL, "IBM", &quote) == SOAP_OK)

      std::cout << "Current IBM Stock Quote = " << quote << std::endl;

   else // an error occurred

      soap_print_fault(&soap, stderr); // stderr中顯示錯(cuò)誤信息

   soap_destroy(&soap); // 刪除類實(shí)例(僅用于C++中)

   soap_end(&soap); // 清除運(yùn)行環(huán)境變量

   soap_done(&soap); // 卸載運(yùn)行環(huán)境變量

   return 0;

}

 

調(diào)用成功后,存根例程返回SOAP_OK同時(shí)quote變量保存著股票信息;如果調(diào)用失敗則產(chǎn)生一個(gè)錯(cuò)誤,同時(shí)通過soap_print_fault函數(shù)顯示錯(cuò)誤信息。gSOAP編譯器同時(shí)為C++客戶端程序生成了一個(gè)代理類。

 

#include "soapnet_DOT_xmethods_DOT_services_DOT_stockquote_DOT_StockQuoteBindingProxy.h" // 獲得代理

#include "net_DOT_xmethods_DOT_services_DOT_stockquote_DOT_StockQuoteBinding.nsmap" // 包含命名空間表

int main()

{

   net q; // "net" 是這個(gè)服務(wù)代理類的短名稱

   float r;

   if (q.ns1__getQuote("IBM", r) == SOAP_OK)

      std::cout << r << std::endl;

   else

      soap_print_fault(q.soap, stderr);

   return 0;

}

代理類的構(gòu)造函數(shù)定義并初始化了一個(gè)gSOAP環(huán)境變量實(shí)例。所有的HTTPSOAP/XML處理被隱藏在后臺(tái)處理。你可以改變WSDL解析器生成的頭文件中web服務(wù)的名稱。web服務(wù)的名字是由WSDL內(nèi)容中萃取的,并不總是短名稱格式的。你可以隨意更改這個(gè)條目

//gSOAP ns1 service name: net_DOT_xmethods_DOT_services_DOT_stockquote_DOT_StockQuoteBinding來使用一個(gè)更合適的名字。這個(gè)名字將決定代理類文件及XML命名空間表文件的名字。

 

下面的函數(shù)可以用來建立一個(gè)gSOAP運(yùn)行環(huán)境(struct soap):

soap_init(struct soap *soap) 初始化運(yùn)行環(huán)境變量(只需要執(zhí)行一次)

soap_init1(struct soap *soap, soap_mode iomode) 初始化運(yùn)行環(huán)境變量同時(shí)設(shè)置in/out模式

soap_init2(struct soap *soap, soap_mode imode, soap_mode omode) 初始化運(yùn)行環(huán)境變量同時(shí)分別設(shè)置in/out模式

struct soap *soap_new() 定義、初始化運(yùn)行環(huán)境并返回一個(gè)執(zhí)行運(yùn)行環(huán)境的指針

struct soap *soap_new1(soap_mode iomode) 定義、初始化運(yùn)行環(huán)境并返回一個(gè)執(zhí)行運(yùn)行環(huán)境的指針并設(shè)置in/out模式

struct soap *soap_new2(soap_mode imode, soap_mode omode) 定義、初始化運(yùn)行環(huán)境并返回一個(gè)執(zhí)行運(yùn)行環(huán)境的指針并分別設(shè)置in/out

struct soap *soap_copy(struct soap *soap) 定義一個(gè)新的環(huán)境變量并將現(xiàn)有環(huán)境信息賦值給新的變量

soap_done(struct soap *soap) 重置、關(guān)閉連接,清除環(huán)境變量

 

環(huán)境變量可以在程序中任意次數(shù)的使用。每個(gè)新的線程就需要一個(gè)新的環(huán)境變量實(shí)例。當(dāng)例子中的客戶端程序執(zhí)行時(shí),SOAP請(qǐng)求通過soap_call_ns1__getQuote函數(shù)來調(diào)用,它生成下面的SOAP RPC請(qǐng)求信息:

POST /soap HTTP/1.1

Host: services.xmethods.net

Content-Type: text/xml

Content-Length: 529

SOAPAction: ""

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xmlns:xsd="http://www.w3.org/2001/XMLSchema"

   xmlns:ns1="urn:xmethods-delayed-quotes"

   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

<SOAP-ENV:Body>

<ns1:getQuote>

<symbol>IBM</symbol>

</ns1:getQuote>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

XMethods Delayed Stock Quote 服務(wù)返回如下的信息:

HTTP/1.1 200 OK

Date: Sat, 25 Aug 2001 19:28:59 GMT

Content-Type: text/xml

Server: Electric/1.0

Connection: Keep-Alive

Content-Length: 491

<?xml version="1.0" encoding="UTF-8"?>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xmlns:xsd="http://www.w3.org/2001/XMLSchema"

   xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"

   soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/?

<soap:Body>

<n:getQuoteResponse xmlns:n="urn:xmethods-delayed-quotes?

<Result xsi:type="xsd:float?41.81</Result>

</n:getQuoteResponse>

</soap:Body>

</soap:Envelope>

 

服務(wù)返回的信息通過存根例程來解析,并保存在soap_call_ns1__getQuote函數(shù)的quote參數(shù)中。客戶端程序可以在任意時(shí)間多次調(diào)用遠(yuǎn)程方法。請(qǐng)看下面的例子:

...

struct soap soap;

float quotes[3]; char *myportfolio[] = {"IBM", "MSDN"};

soap_init(&soap); // need to initialize only once

for (int i = 0; i < 3; i++)

   if (soap_call_ns1__getQuote(&soap, "http://services.xmethods.net:80/soap", "", myportfolio[i], &quotes[i]) != SOAP_OK)

      break;

if (soap.error) // an error occurred

   soap_print_fault(&soap, stderr);

soap_end(&soap); // clean up all deserialized data

...

這個(gè)客戶端程序通過調(diào)用ns1__getQuote存根例程來為數(shù)組中的每個(gè)股票代碼獲得信息。上面的例子給我們示范了使用gSOAP創(chuàng)建一個(gè)SOAP客戶端時(shí)多么容易的事情啊。

 

2.10 gSOAP文檔翻譯計(jì)劃(8.1.2~8.1.3

8.1.2 關(guān)于命名空間

函數(shù)ns1__getQuote(上節(jié)提到的)中,使用了ns1__作為遠(yuǎn)程方法的命名空間。使用命名空間是為了防止遠(yuǎn)程方法名沖突,比方多個(gè)服務(wù)中使

用同一個(gè)遠(yuǎn)程方法名的情況。

 

命名空間前綴及命名空間名稱同時(shí)也被用來驗(yàn)證SOAP信息的內(nèi)容有效性。存根例程通過命名空間表中的信息來驗(yàn)證服務(wù)返回信息。命名空間表在運(yùn)行時(shí)被取出用于解析命名空間綁定,反序列化數(shù)據(jù)結(jié)構(gòu),解碼并驗(yàn)證服務(wù)返回信息。命名空間表不應(yīng)該包含在gSOAP預(yù)編譯器所需輸入的頭文件中。在18.2節(jié)中將會(huì)對(duì)命名空間表做詳細(xì)介紹。

 

Delayed Stock Quote服務(wù)客戶端的命名空間表如下:

struct Namespace namespaces[] =

{   // {"命名前綴", "空間名稱"}

   {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"}, // 必須是第一行

   {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"}, // 必須是第二行

   {"xsi", "http://www.w3.org/2001/XMLSchema-instance"}, // 必須是第三行

   {"xsd", "http://www.w3.org/2001/XMLSchema"}, // 2001 XML 大綱

   {"ns1", "urn:xmethods-delayed-quotes"}, // 通過服務(wù)描述獲取

   {NULL, NULL} // 結(jié)束

};

 

第一行命名空間是SOAP1.1協(xié)議默認(rèn)命名空間。事實(shí)上,命名空間表就是用來讓程序員可以規(guī)定SOAP編碼方式,能夠用包含命名空間的命名空間前綴來滿足指定SOAP服務(wù)的命名空間需求的。舉例來說,使用前面命名空間表中定義的命名空間前綴ns1,存根例程就可以對(duì)getQuote方法的請(qǐng)求進(jìn)行編碼。這個(gè)過程由gSOAP預(yù)編譯器通過在getQuote.h文件中定義的包含前綴ns1ns1__getQuote函數(shù)自動(dòng)完成。通常,如果要在遠(yuǎn)程方法名,結(jié)構(gòu)名,類名,字段名等結(jié)構(gòu)或類中使用命名空間前綴,就必須在命名空間表中進(jìn)行定義。命名空間表將會(huì)被存根例程封裝,并按下面的形式輸出:

...

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xmlns:xsd="http://www.w3.org/2001/XMLSchema"

   xmlns:ns1="urn:xmethods-delayed-quotes"

   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

...

這個(gè)命名空間綁定將被SOAP服務(wù)用來驗(yàn)證SOAP請(qǐng)求。

 

8.1.3 例子

使用命名空間前綴可以解決在不同的服務(wù)中使用相同名稱的遠(yuǎn)程方法的問題,看下面的例子:

// Contents of file "getQuote.h":

int ns1__getQuote(char *symbol, float &Result);

int ns2__getQuote(char *ticker, char *&quote);

 

這個(gè)例子允許客戶端程序使用不同的命名空間以便連接到不同的服務(wù)程序執(zhí)行其中的遠(yuǎn)程方法。命名空間前綴也可以用在類聲明中使用,在XML大綱中區(qū)分同名但不同命名空間的SOAP值。例如:

class e__Address // an electronic address

{

   char *email;

   char *url;

};

class s__Address // a street address

{

   char *street;

   int number;

   char *city;

};

 

在生成的序列化函數(shù)中,使用e__Address的一個(gè)實(shí)例來表示e命名空間前綴的一個(gè)地址元素類型。

<e:Address xsi:type="e:Address">

<email xsi:type="string">me@home</email>

<url xsi:type="string">www.me.com</url>

</e:Address>

s__Address的一個(gè)實(shí)例來表示s命名空間前綴的一個(gè)地址元素類型。

<s:Address xsi:type="s:Address">

<street xsi:type="string">Technology Drive</street>

<number xsi:type="int">5</number>

<city xsi:type="string">Softcity</city>

</s:Address>

客戶端程序的命名空間表必須有es的數(shù)據(jù)類型定義:

struct Namespace namespaces[] =

{ ...

   {"e", "http://www.me.com/schemas/electronic-address"},

   {"s", "http://www.me.com/schemas/street-address"},

...

 

命名空間表必須作為客戶端程序的一部分,使客戶端程序在運(yùn)行時(shí)可以對(duì)數(shù)據(jù)進(jìn)行序列化及反序列化。

 

2.11 gSOAP翻譯計(jì)劃(8.1.4~8.1.6

8.1.4 如何建立客戶端程序代理類

用于C++客戶端程序的代理類信息是由gSOAP預(yù)編譯器自動(dòng)創(chuàng)建的。為了說明代理類的生成過程,我們?cè)?span lang="EN-US">getQuote.h頭文件中加入一些信息,以便gSOAP預(yù)編譯器可以生成代理類。這些信息就類似于WSDL解析器自動(dòng)生成的頭文件中就已經(jīng)包含的信息。

//"getQuote.h"的內(nèi)容:

//gSOAP ns1 service name: Quote

//gSOAP ns1 service location: http://services.xmethods.net/soap

//gSOAP ns1 service namespace: urn:xmethods-delayed-quotes

//gSOAP ns1 service style: rpc

//gSOAP ns1 service encoding: encoded

//gSOAP ns1 service method-action: getQuote ""

int ns1__getQuote(char *symbol, float &Result);

 

前三行指令用于定義代理類的名稱,服務(wù)地址,命名空間。第四行、第五行指令定義了使用SOAP RPC編碼方式。最后一行定義了可選的SOAPAction。當(dāng)需要SOAPAction時(shí),這行信息將提供給每個(gè)遠(yuǎn)程方法。使用soapcpp2對(duì)該頭文件進(jìn)行編譯后,將會(huì)產(chǎn)生soapQuoteProxy.h文件。它包含下面的內(nèi)容:

#include "soapH.h"

class Quote

{ public:

   struct soap *soap;

   const char *endpoint;

   Quote() { soap = soap_new(); endpoint = "http://services.xmethods.net/soap"; };

   ~Quote() { if (soap) { soap_destroy(soap); soap_end(soap); soap_done(soap); free((void*)soap); }};

   int getQuote(char *symbol, float &Result) { return soap ? soap_call_ns1__getQuote(soap, endpoint, "", symbol, Result) :

SOAP_EOM; };

};

 

為了能夠在運(yùn)行時(shí)刻對(duì)gSOAP環(huán)境變量及命名空間進(jìn)行定制,上述兩個(gè)變量被定義程全局變量。生成的代理類可以同命名空間表一起包含在客戶端程序中,請(qǐng)看下面的例子:

#include "soapQuoteProxy.h" // 獲得代理類

#include "Quote.nsmap" // 獲得命名空間綁定

int main()

{

   Quote q;

   float r;

   if (q.ns1__getQuote("IBM", r) == SOAP_OK)

      std::cout << r << std::endl;

   else

      soap_print_fault(q.soap, stderr);

   return 0;

}

 

Quote構(gòu)造函數(shù)定義并初始化了一個(gè)gSOAP運(yùn)行環(huán)境實(shí)例。所有的HTTPSOAP/XML進(jìn)程都被隱藏在后臺(tái)自動(dòng)執(zhí)行。如果你需要多個(gè)命名空間表或要聯(lián)合多個(gè)客戶端,你可以在執(zhí)行soapcpp2時(shí)添加參數(shù)-n-p來生成命名空間表以防止沖突。詳細(xì)信息請(qǐng)看9.118.33節(jié)。同時(shí),你可以使用C++代碼命名空間來創(chuàng)建一個(gè)命名空間限制的代理類,詳細(xì)信息請(qǐng)看18.32節(jié)。

 

8.1.5 XSD 類型編碼

許多SOAP服務(wù)需要在SOAP負(fù)載中使用XML編碼。在gSOAP預(yù)編譯器中使用的默認(rèn)編碼為SOAP RPC編碼。然而,使用XSD類型編碼可以改善互操作性。XSD類型在頭文件中用typedef定義。舉個(gè)例子,下面的定義將C/C++類型轉(zhuǎn)換為XSD類型:

// Contents of header file:

...

typedef char *xsd__string; // encode xsd__string value as the xsd:string schema type

typedef char *xsd__anyURI; // encode xsd__anyURI value as the xsd:anyURI schema type

typedef float xsd__float; // encode xsd__float value as the xsd:float schema type

typedef long xsd__int; // encode xsd__int value as the xsd:int schema type

typedef bool xsd__boolean; // encode xsd__boolean value as the xsd:boolean schema type

typedef unsigned long long xsd__positiveInteger; // encode xsd__positiveInteger value as the xsd:positiveInteger schema type

...

 

這些簡(jiǎn)單的聲明告訴gSOAP預(yù)編譯器當(dāng)遠(yuǎn)程方法參數(shù)中使用上述定義的類型時(shí),就把相關(guān)的C++類型轉(zhuǎn)當(dāng)作內(nèi)建的XSD類型進(jìn)行編碼、解碼。同時(shí),使用typedef不需要使用內(nèi)建C++類型的客戶端或服務(wù)端程序更改現(xiàn)有代碼(但只是當(dāng)參數(shù)為簡(jiǎn)單的C++類型時(shí),請(qǐng)參看11.2.2節(jié)來使用XSD類型表示組合的數(shù)據(jù)類型)。

 

8.1.6 例子

重新考慮一席getQuote的例子。現(xiàn)在用XSD類型來重寫代碼:

// Contents of file "getQuote.h":

typedef char *xsd__string;

typedef float xsd__float;

int ns1__getQuote(xsd__string symbol, xsd__float &Result);

 

使用預(yù)編譯器編譯這個(gè)頭文件,將會(huì)生成與原來相同的存根例程代碼:

int soap_call_ns1__getQuote(struct soap *soap, char *URL, char *action, char *symbol, float &Result);

 

客戶端程序不需要進(jìn)行任何改動(dòng),即可使用XSD類型類編碼、解碼數(shù)據(jù)類型信息了。舉個(gè)例子,當(dāng)客戶端程序調(diào)用代理時(shí),代理方法用xsd:string類型產(chǎn)生一個(gè)SOAP請(qǐng)求:

...

<SOAP-ENV:Body>

<ns1:getQuote><symbol xsi:type="xsd:string">IBM</symbol>

</ns1:getQuote>

</SOAP-ENV:Body>

...

服務(wù)端的返回碼為:

...

<soap:Body>

<n:getQuoteResponse xmlns:n="urn:xmethods-delayed-quotes">

<Result xsi:type="xsd:float">41.81</Result>

</n:getQuoteResponse>

</soap:Body>

posted on 2008-05-28 16:24 肥仔 閱讀(34531) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 網(wǎng)絡(luò)編程

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            一本色道久久综合亚洲精品婷婷| 亚洲综合色视频| 一区二区久久久久久| 亚洲人被黑人高潮完整版| 1024国产精品| 99精品国产一区二区青青牛奶| 99精品视频免费观看视频| 亚洲一区欧美激情| 久久嫩草精品久久久精品一| 欧美大尺度在线| 亚洲精选视频在线| 午夜亚洲精品| 美日韩精品免费观看视频| 欧美日韩福利视频| 国产日韩精品视频一区二区三区| 黄色成人av| 亚洲制服少妇| 欧美风情在线观看| 亚洲一级免费视频| 麻豆成人91精品二区三区| 欧美色偷偷大香| 亚洲第一天堂无码专区| 亚洲图色在线| 免费在线一区二区| 中文成人激情娱乐网| 久久精品30| 国产精品www| 亚洲黄色高清| 欧美在线观看视频| 亚洲精品欧美激情| 久久色在线播放| 国产精品一区二区三区四区五区| 亚洲国产精品福利| 久久精品动漫| 一区二区三区毛片| 欧美国产综合| 老司机精品视频一区二区三区| 亚洲美女中文字幕| 久久精品盗摄| 中文国产一区| 欧美国产另类| 永久免费精品影视网站| 午夜精彩视频在线观看不卡| 欧美国产日韩a欧美在线观看| 亚洲欧美日韩视频二区| 欧美日本国产一区| 亚洲日韩欧美一区二区在线| 久久精品亚洲热| 亚洲一区bb| 欧美日韩在线不卡一区| 亚洲精品欧美一区二区三区| 美女黄色成人网| 久久国产精品99精品国产| 国产精品成人一区二区三区夜夜夜 | 国产精品第十页| 亚洲免费成人av电影| 欧美a级片网| 久久久精品久久久久| 国产美女精品免费电影| 亚洲女人小视频在线观看| 亚洲精品资源美女情侣酒店| 巨胸喷奶水www久久久免费动漫| 国产欧美精品一区二区三区介绍 | 猫咪成人在线观看| 香蕉成人伊视频在线观看| 国产精品国产| 欧美一区二区成人6969| 亚洲一区国产精品| 国产日韩精品视频一区| 久久精品中文字幕免费mv| 午夜精品久久久| 国产一级揄自揄精品视频| 欧美一区二区三区精品电影| 亚洲欧美卡通另类91av| 国产午夜亚洲精品理论片色戒| 欧美在线在线| 久久久久五月天| 亚洲国产专区校园欧美| 亚洲高清三级视频| 欧美黄在线观看| 亚洲一级免费视频| 亚洲欧美另类国产| 在线播放日韩专区| 亚洲美女中出| 国产日韩在线亚洲字幕中文| 另类酷文…触手系列精品集v1小说| 亚洲精品中文在线| 一区二区三区免费网站| 国产精品人人爽人人做我的可爱| 午夜精品久久久久久久99热浪潮| 亚洲欧美日本另类| 亚洲第一区在线| a4yy欧美一区二区三区| 国产欧美高清| 亚洲人成绝费网站色www| 国产精品久久久久久五月尺| 久久久久久网址| 欧美精品一区二区精品网 | 一区二区三区国产| 国产一区在线观看视频| 亚洲欧洲日本在线| 国产精品一二三四| 亚洲国产精品一区二区久| 国产精品乱码人人做人人爱| 久久免费一区| 国产精品成人aaaaa网站 | 在线视频欧美日韩| 精品白丝av| 亚洲一区二区三区高清不卡| 尤物在线观看一区| 亚洲深夜福利视频| 亚洲理论在线| 久久亚洲综合色一区二区三区| 一本色道久久综合亚洲精品婷婷 | 国产精品美女久久| 亚洲黄色片网站| 狠狠色综合网| 亚洲在线一区| 在线视频免费在线观看一区二区| 久久久水蜜桃av免费网站| 香蕉乱码成人久久天堂爱免费 | 亚洲亚洲精品在线观看| 久久天天躁夜夜躁狠狠躁2022 | 欧美国产一区在线| 国内精品伊人久久久久av一坑| 中文精品99久久国产香蕉| 亚洲日韩视频| 久久中文字幕一区| 久久嫩草精品久久久精品一| 欧美日韩亚洲一区二区三区在线 | 欧美日韩视频第一区| 亚洲激情成人在线| 亚洲国产成人精品女人久久久| 亚洲欧美美女| 伊人精品成人久久综合软件| 亚洲视频在线观看网站| 中文日韩电影网站| 久久精品一区四区| 久久亚洲综合色一区二区三区| 国产伦精品一区二区三区免费迷| 夜夜嗨av一区二区三区网站四季av | 亚洲风情亚aⅴ在线发布| 久久成人久久爱| 久久久久久久综合| 黄色国产精品一区二区三区| 欧美一级久久久久久久大片| 欧美一区二区三区在线观看视频| 国产精品久久久久影院色老大| 一本色道久久综合狠狠躁篇的优点 | 亚洲乱码精品一二三四区日韩在线| 欧美在线中文字幕| 久久在精品线影院精品国产| 精品成人在线视频| 欧美a级一区| 亚洲免费久久| 欧美亚洲一级| 极品日韩久久| 欧美成人一区二区在线| 亚洲精品日韩久久| 欧美一级片久久久久久久| 国产亚洲欧美日韩日本| 久久精品亚洲精品国产欧美kt∨| 久久久亚洲人| 亚洲日本久久| 国产精品久久久久99| 欧美一区二区三区在线观看| 欧美成人一品| 亚洲欧美成人一区二区三区| 国产日韩在线看| 玖玖综合伊人| 一本久道综合久久精品| 久久xxxx| 亚洲日韩第九十九页| 欧美午夜国产| 久久五月天婷婷| 一区二区成人精品| 久久综合久久88| 亚洲素人在线| 黄色亚洲在线| 欧美三级在线播放| 久久久久国产成人精品亚洲午夜| 亚洲日本久久| 久久久伊人欧美| 亚洲少妇诱惑| 亚洲国产黄色| 国产区在线观看成人精品| 免费av成人在线| 午夜亚洲性色福利视频| 亚洲国产精品一区二区第一页 | 99在线热播精品免费99热| 国产伦精品一区二区三区高清| 免费成人你懂的| 欧美一区二区三区另类 | 亚洲天堂成人| 国产视频精品xxxx| 欧美视频二区| 欧美大片在线观看| 久久久久久久999| 午夜电影亚洲| 亚洲一级免费视频|