欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
淺談Java中的通信機制及與C/C++ API的集成
背景:
對于舊有系統的改造和升級,最苦惱的莫過(guò)于跨平臺,跨語(yǔ)言。我的一個(gè)朋友最近從Java專(zhuān)向了專(zhuān)攻.NET——因為.NET的CLR既有類(lèi)似Java虛擬機概念這種已經(jīng)被證明很成功的底層托管能力。又對于Windows的就有桌面應用提供了良好的兼容。
最近我的一個(gè)個(gè)人項目也面臨著(zhù)這樣的需求。一個(gè)C語(yǔ)言開(kāi)發(fā)的中間件,通過(guò)API暴露給二次開(kāi)發(fā)及插件應用?,F在由于對其應用的需求變得日趨復雜,而且正在脫離Unix的管理環(huán)境,走向基于JWS這樣的BCS管理。有朋友推薦我用JNI,但這樣一是增加了耦合度,二是讓Java睡在JNI感覺(jué)不太安穩。在認知了上下兩層的系統平臺后,問(wèn)題變得明朗起來(lái):如何在HTTP協(xié)議下實(shí)現Java和C之間的交互?
思路:
本人對Java比較熟悉,先從Java的角度入手,Java間的通信方法:
1 通過(guò)URL,Applet/JWS訪(fǎng)問(wèn)被影射到URL的動(dòng)態(tài)資源(Servlet)
2 通過(guò)URL,Applet/JWS訪(fǎng)問(wèn)共享的靜態(tài)資源(Server定期更新靜態(tài)資源)
3 通過(guò)序列化和反序列化,實(shí)現簡(jiǎn)單對象的傳輸(比如Resin的Hessian框架就提供了這種通信的方式)
4 通過(guò)一些工具做代碼生成,利用Web Services實(shí)現客戶(hù)端和服務(wù)端的交互
此外脫離HTTP,還可以做RMI,socket編程

現在問(wèn)題是通信的一端由Java變成了C/C++, 于是, 解決方案1需要把動(dòng)態(tài)資源由CGI來(lái)定義,而方案3變得不再適用。于是方案有:
1 通過(guò)URL,Applet/JWS訪(fǎng)問(wèn)被影射到URL的動(dòng)態(tài)資源(CGI)
2 通過(guò)URL,Applet/JWS訪(fǎng)問(wèn)共享的靜態(tài)資源(Server定期更新靜態(tài)資源)
3 通過(guò)一些工具做代碼生成,利用Web Services實(shí)現客戶(hù)端和服務(wù)端的交互(×××這是我們討論的重點(diǎn)×××)

解決方案:
現在針對上文提出的3中通信方式中的1和3談一談實(shí)現的方法,2的實(shí)現方案比較靈活,需要發(fā)揮大家的想象力了:)
針對CGI:
首先CGI可以配置在各種主流的服務(wù)器中作為后端的腳本運行。大家可能對Servlet更熟悉一些。
CGI可以用腳本寫(xiě),也可以用C來(lái)實(shí)現。CGI被觸發(fā)后,通過(guò)系統的環(huán)境變量來(lái)獲得輸入,在處理完畢后向標準輸出中輸出結果。
由此可以想見(jiàn),Web服務(wù)器在接受到來(lái)自HTTP協(xié)議的請求后,首先把請求的參數獲取到,然后設置到環(huán)境變量里。
根據對訪(fǎng)問(wèn)的URL的解析和服務(wù)器自身的配置,找到服務(wù)于請求的CGI程序的位置,然后執行這個(gè)程序。
這個(gè)程序被執行后通過(guò)環(huán)境變量得到了服務(wù)器先前設置在環(huán)境變量中的參數。在經(jīng)過(guò)一些復雜的邏輯操作后,向標準輸出輸出結果。
這個(gè)輸出又被Web服務(wù)器所捕獲,轉而傳遞回請求的客戶(hù)端。
更多關(guān)于CGI的知識和理解,大家可以通過(guò)google來(lái)尋找答案

上述CGI的方式可以讓我們直接獲取到結果,但是方案比較原始和基礎。其缺點(diǎn)有:
1 需要自己制定類(lèi)型傳輸協(xié)議,做封裝和拆封,否則只支持字符串
2 我們不會(huì )為了要用C的API就給它裝一個(gè)或者自己實(shí)現一個(gè)Web服務(wù)器的,這讓我們的底層程序顯得蠢笨而冗余。我們希望能有一個(gè)超薄的Server外殼,
在對API封裝后,通過(guò)某個(gè)端口進(jìn)行開(kāi)放即可。

針對Web Servcies:
Based on上面的兩個(gè)不足,我們只能把希望寄托在Web Services身上了,
筆者在這里推薦給大家的是在C/C++很著(zhù)名的Web Services工具gSOAP。大家可以到http://gsoap2.sourceforge.net/上去下載這個(gè)工具。
通過(guò)這個(gè)工具,我們可以做到:
1 一個(gè)Stand-alone的服務(wù)器外殼
2 一個(gè)根據API程序自動(dòng)生成的Web Services服務(wù)
3 一個(gè)WSDL描述符文件

下面說(shuō)明有關(guān)基于gSOAP的Web Services C服務(wù)端和Java客戶(hù)端的運行機理,及通過(guò)Java客戶(hù)端訪(fǎng)問(wèn)gSOAP的Web Services的過(guò)程中需要注意的問(wèn)題。

客戶(hù)根據 WSDL 描述文檔,會(huì )生成一個(gè) SOAP 請求消息。Web Services 都是放在Web服務(wù)器后面,客戶(hù)生成的SOAP請求會(huì )被嵌入在一個(gè)HTTP POST請求中,發(fā)送到 Web 服務(wù)器來(lái)。Web 服務(wù)器再把這些請求轉發(fā)給 Web Services 請求處理器。請求處理器的作用在于,解析收到的 SOAP 請求,調用 Web Services,然后再生成相應的 SOAP 應答。Web 服務(wù)器得到 SOAP 應答后,會(huì )再通過(guò) HTTP應答的方式把信息送回到客戶(hù)端。
WSDL是Web服務(wù)中客戶(hù)端和服務(wù)端溝通的橋梁,描述了對象提供的方法。SOAP幫我們制定了一份被官方認可的對象的封裝方法。有了WSDL,客戶(hù)端只關(guān)心如何把參數用Soap封裝起來(lái)發(fā)出去,并獲取結果。服務(wù)端只關(guān)心如何對Soap進(jìn)行拆包->服務(wù)->封包。gSOAP可以幫我們實(shí)現上述過(guò)程中的拆包和封包,而我們可以只關(guān)心服務(wù)的實(shí)現。

言歸正傳,在這里我們以一個(gè)簡(jiǎn)單的實(shí)現加、減、開(kāi)放的Web Services的服務(wù)為例子,介紹gSOAP的使用:
為了發(fā)布這個(gè)Web服務(wù),首先我們需要把服務(wù)的接口定義好,這個(gè)服務(wù)可能是一個(gè)現有服務(wù)的Adapter,為此我們定義頭文件
calc.h:

Java代碼
  1. typedef double xsd__double;   
  2. int ns__add(xsd__double a, xsd__double b, xsd__double &result);   
  3. int ns__sub(xsd__double a, xsd__double b, xsd__double &result);   
  4. int ns__sqrt(xsd__double a, xsd__double &result);   

注意到這里面我們把double定義成了xsd__double(兩個(gè)下劃線(xiàn)),這是為了告訴gSOAP,我們需要的soap格式和WSDL格式是基于Document/literal的而非rpc/encoded.為了不把事情搞復雜,在這里我只能說(shuō),Java1.6自帶的Web Services工具只支持Document/literal格式的WSDL,所以我們生成這種格式的WSDL。至于這兩種格式之間選擇和他們的long story,大家可以參考下面的文章:
http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/
編寫(xiě)好頭文件后,我們就可以利用gSOAP提供的工具進(jìn)行生成了:
/usr/lib/gsoap-2.7/bin/soapcpp2 -S -2 calc.h
生成的主要文件詳見(jiàn)附件。
下面我們實(shí)現calc.h中定義的函數:
Java代碼
  1. // Contents of file "calc.cpp":    
  2. #include "soapH.h"    
  3. #include "ns.nsmap"    
  4. #include <math.h>    
  5. int main()   
  6. {   
  7.    struct soap soap;   
  8.    int m, s; // master and slave sockets   
  9.    soap_init(&soap);   
  10.    m = soap_bind(&soap, "localhost"9999100);   
  11.    if (m < 0)   
  12.       soap_print_fault(&soap, stderr);   
  13.    else  
  14.    {   
  15.       fprintf(stderr, "Socket connection successful: master socket = %d\n", m);   
  16.       for (int i = 1; ; i++)   
  17.       {   
  18.          s = soap_accept(&soap);   
  19.          if (s < 0)   
  20.          {   
  21.             soap_print_fault(&soap, stderr);   
  22.             break;   
  23.          }   
  24.          fprintf(stderr, "%d: accepted connection from IP=%d.%d.%d.%d socket=%d", i,   
  25.             (soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF, s);   
  26.          if (soap_serve(&soap) != SOAP_OK) // process RPC request   
  27.             soap_print_fault(&soap, stderr); // print error   
  28.          fprintf(stderr, "request served\n");   
  29.          soap_destroy(&soap); // clean up class instances   
  30.          soap_end(&soap); // clean up everything and close socket   
  31.       }   
  32.    }   
  33.    soap_done(&soap); // close master socket and detach environment   
  34. }   
  35. // Implementation of the "add" remote method:    
  36. int ns__add(struct soap *soap, double a, double b, double &result)    
  37. {    
  38.    result = a + b;    
  39.    return SOAP_OK;    
  40. }    
  41. // Implementation of the "sub" remote method:    
  42. int ns__sub(struct soap *soap, double a, double b, double &result)    
  43. {    
  44.    result = a - b;    
  45.    return SOAP_OK;    
  46. }    
  47. // Implementation of the "sqrt" remote method:    
  48. int ns__sqrt(struct soap *soap, double a, double &result)    
  49. {    
  50.    if (a >= 0)    
  51.    {    
  52.       result = sqrt(a);    
  53.       return SOAP_OK;    
  54.    }    
  55.    else  
  56.    {    
  57.       return soap_sender_fault(soap, "Square root of negative value""I can only compute the square root of a non-negative value");   
  58.    }    
  59. }   

前文提到過(guò),我們不希望為了發(fā)布基于Web Services的C語(yǔ)言的API而開(kāi)發(fā)或應用一個(gè)大的Web服務(wù)器。我們代碼中的main函數實(shí)現了一個(gè)最簡(jiǎn)單的Web Server(基于Socket).這個(gè)Server利用gSOAP生成的API來(lái)提供針對SOAP的處理。
下面我們把這個(gè)嵌入式的web server編譯,編譯的時(shí)候注意stdsoap2.cpp這個(gè)文件是從gSOAP包中拷貝而來(lái),不是自動(dòng)生成的,大家下載gSOAP后直接就能找到這個(gè)文件及其頭文件。
g++ -o calcServer calc.cpp soapC.cpp soapServer.cpp stdsoap2.cpp
一個(gè)以Web Servers形式提供的C API誕生了。
在server端執行./calcServer

下面討論如何用Java1.6的自帶工具生成一個(gè)客戶(hù)端stub:
把gSOAP生成的WSDL拷貝到我們的Java開(kāi)發(fā)環(huán)境中來(lái),按照Web Services Server中定義的端口和服務(wù)器,配置參數生成客戶(hù)端Web Services代碼:
/usr/lib/jvm/jdk1.6.0_03/bin/wsimport -extension -httpproxy:localhost:9999 -verbose ns.wsdl

生成后,把這個(gè)環(huán)境添加到eclipse的編譯環(huán)境中來(lái),然后在eclipse中建一個(gè)新的類(lèi):
Java代碼
  1. class Test {   
  2.     public static void main(String args[]) {   
  3.         Service service = new Service();   
  4.         double h = service.getService().sub(200001);   
  5.         System.out.println(h);   
  6.     }   
  7. }  

運行后得到結果19999.0

總結:當集成Java和C兩種平臺時(shí),我們可以有多種解決方案,但首先我們應該想到gSOAP因為它能夠很出色地完成任務(wù)。
文中相關(guān)代碼:
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
gSoap使用入門(mén)(2)----自定義接口頭文件
探討C 、C#和JAVA:webservice互操作問(wèn)題
用gSOAP調用Web Services
用C實(shí)現WebService(ZZ)-蝸居
使用gsoap介紹
深入研究SOAP消息
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久