《Java網(wǎng)絡(luò)程序設(shè)計(jì)》課件-第9章_第1頁(yè)
《Java網(wǎng)絡(luò)程序設(shè)計(jì)》課件-第9章_第2頁(yè)
《Java網(wǎng)絡(luò)程序設(shè)計(jì)》課件-第9章_第3頁(yè)
《Java網(wǎng)絡(luò)程序設(shè)計(jì)》課件-第9章_第4頁(yè)
《Java網(wǎng)絡(luò)程序設(shè)計(jì)》課件-第9章_第5頁(yè)
已閱讀5頁(yè),還剩44頁(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)介

第9章遠(yuǎn)程方法調(diào)用

9.1RMI9.2RMI工作機(jī)制9.3RMI實(shí)現(xiàn)技術(shù)

9.1RMI

9.1.1RMI的概念

分布式計(jì)算的實(shí)質(zhì)是“要求運(yùn)行在不同地址空間不同主機(jī)上的對(duì)象互相調(diào)用?!备鞣N分布式系統(tǒng)都有自己的調(diào)用協(xié)議,著名的解決方案有:

●?公共對(duì)象請(qǐng)求代理體系結(jié)構(gòu)(CommonObjectRequestBrokerArchitecture,CORBA)的IIOP(InternetInterORBProtocol,互聯(lián)網(wǎng)內(nèi)部對(duì)象請(qǐng)求代理協(xié)議)。CORBA體系結(jié)構(gòu)是對(duì)象管理組織(ObjectManagermentGroup,OMG)為解決分布式處理環(huán)境(DistributedComputingEnviornment,DCE)中,硬件和軟件系統(tǒng)的互連而提出的一種解決方案?!?微軟事務(wù)服務(wù)器(MicrosoftTransactionServer,MTS)中的分布式組件對(duì)象模型(DistributedComponentObjectModel,DCOM)。DCOM是一系列微軟的概念和程序接口,利用這個(gè)接口,客戶端程序?qū)ο竽軌蛘?qǐng)求來(lái)自網(wǎng)絡(luò)中另一臺(tái)計(jì)算機(jī)上的服務(wù)器程序?qū)ο蟆?/p>

●?RMI。RMI是Java的一組開(kāi)發(fā)分布式應(yīng)用程序的API。RMI使用Java語(yǔ)言接口定義了遠(yuǎn)程對(duì)象,它集合了Java序列化和Java遠(yuǎn)程方法協(xié)議(JavaRemoteMethodProtocol)。它是一種機(jī)制,能夠讓在某個(gè)Java虛擬機(jī)上的對(duì)象調(diào)用另一個(gè)Java虛擬機(jī)中對(duì)象上的方法,可以調(diào)用任何實(shí)現(xiàn)該遠(yuǎn)程接口的對(duì)象。

Java語(yǔ)言之所以被稱為網(wǎng)絡(luò)開(kāi)發(fā)語(yǔ)言,因?yàn)樗婚_(kāi)始就與Web開(kāi)發(fā)聯(lián)系在一起,并擁有“強(qiáng)大開(kāi)發(fā)分布式網(wǎng)絡(luò)應(yīng)用”的能力,RMI就是開(kāi)發(fā)百分之百純Java的網(wǎng)絡(luò)分布式應(yīng)用系統(tǒng)的核心解決方案之一。

RMI是Java在JDK1.1中實(shí)現(xiàn)的,是非常重要的底層技術(shù),它大大增強(qiáng)了Java開(kāi)發(fā)分布式應(yīng)用的能力。EJB(EnterpriseJavaBean)就是建立在RMI基礎(chǔ)之上的,現(xiàn)在還有一些開(kāi)源的遠(yuǎn)程調(diào)用組件,其底層技術(shù)也采用了RMI。

RMI使用Java語(yǔ)言接口定義了遠(yuǎn)程對(duì)象,它集合了Java序列化和Java遠(yuǎn)程方法協(xié)議(JavaRemoteMethodProtocol)。簡(jiǎn)單地說(shuō),這樣使原先的程序由在同一操作系統(tǒng)的方法調(diào)用,變成了在不同操作系統(tǒng)之間程序的方法調(diào)用。由于J2EE是分布式程序平臺(tái),因而RMI機(jī)制可實(shí)現(xiàn)程序組件在不同操作系統(tǒng)之間的通信。比如,一個(gè)EJB可以通過(guò)RMI調(diào)用Web上另一臺(tái)機(jī)器上的EJB遠(yuǎn)程方法,即跨平臺(tái)操作,如圖9-1所示。圖9-1RMI工作原理

RMI以Java為核心,它將Java的安全性和可移植性等強(qiáng)大功能帶給了分布式計(jì)算,所以可將代理和業(yè)務(wù)邏輯等屬性移動(dòng)到網(wǎng)絡(luò)中最合適的地方,例如遠(yuǎn)程的服務(wù)器。RMI可以被看做是遠(yuǎn)程過(guò)程控制(RemoteProcessControl,RPC)的Java版本,但是傳統(tǒng)的RPC并不能很好地應(yīng)用于分布式對(duì)象系統(tǒng)。而RMI則支持存儲(chǔ)于不同地址空間的程序級(jí)對(duì)象之間彼此進(jìn)行通信,實(shí)現(xiàn)遠(yuǎn)程對(duì)象之間的無(wú)縫遠(yuǎn)程調(diào)用。

在Java的RMI規(guī)范中提供的功能有:

●?支持對(duì)存在于不同虛擬機(jī)上的對(duì)象進(jìn)行無(wú)縫的遠(yuǎn)程調(diào)用;●?支持服務(wù)器對(duì)客戶的回調(diào);

●?把分布式對(duì)象模型自然地集成到Java語(yǔ)言里,盡可能從語(yǔ)義上保留Java的面向?qū)ο蟮奶卣鳎?/p>

●?使分布式對(duì)象模型和本地Java對(duì)象模型間的差異明朗;

●?使編寫可靠的分布式應(yīng)用程序盡可能簡(jiǎn)單;

●?保留Javarun-time環(huán)境所提供的安全性;

●?多樣化的遠(yuǎn)程調(diào)用機(jī)制;

●?支持多點(diǎn)傳輸?shù)哪芰Γ?/p>

●?支持分布式的垃圾回收。9.1.2RMI的優(yōu)點(diǎn)

RMI為采用Java對(duì)象的分布式計(jì)算提供了簡(jiǎn)單而直接的途徑,通過(guò)RMI技術(shù)充分體現(xiàn)了“編寫一次就能在任何地方運(yùn)行的模式”。RMI可利用標(biāo)準(zhǔn)Java本機(jī)方法接口JNI與現(xiàn)有的和原有的系統(tǒng)相連接。RMI還可利用標(biāo)準(zhǔn)JDBC類庫(kù)與關(guān)系型數(shù)據(jù)庫(kù)連接,即RMI/JNI和RMI/JDBC相結(jié)合,并且可利用RMI與目前使用非Java語(yǔ)言的現(xiàn)有服務(wù)器進(jìn)行通信。

RMI的主要優(yōu)點(diǎn)如下:

(1)面向?qū)ο?。RMI可將完整的對(duì)象作為參數(shù)和返回值進(jìn)行傳遞,而不僅僅是預(yù)定義的數(shù)據(jù)類型。也就是說(shuō),您可以將類似Java哈希表這樣的復(fù)雜類型作為一個(gè)參數(shù)進(jìn)行傳遞。而在目前的RPC系統(tǒng)中,您只能依靠客戶機(jī)將此類對(duì)象分解成基本數(shù)據(jù)類型,然后傳遞這些數(shù)據(jù)類型,最后在服務(wù)器端重新創(chuàng)建哈希表。RMI則不需額外的客戶程序代碼(將對(duì)象分解成基本數(shù)據(jù)類型),直接跨網(wǎng)傳遞對(duì)象。

(2)可移動(dòng)屬性。RMI可將屬性(類實(shí)現(xiàn)程序)從客戶機(jī)移動(dòng)到服務(wù)器,或者從服務(wù)器移到客戶機(jī)。例如,可以定義一個(gè)檢查雇員開(kāi)支報(bào)告的接口,以便察看雇員是否遵守了公司目前實(shí)行的政策。在開(kāi)支報(bào)告創(chuàng)建后,客戶機(jī)就會(huì)從服務(wù)器端獲得實(shí)現(xiàn)該接口的對(duì)象。如果政策發(fā)生變化,服務(wù)器端就會(huì)開(kāi)始返回使用了新政策的該接口的另一個(gè)實(shí)現(xiàn)程序。不必在用戶系統(tǒng)上安裝任何新的軟件就能在客戶端檢查限制條件,從而向用戶提供快速的反饋,并降低服務(wù)器的工作量。這樣程序就能具備最大的靈活性,因?yàn)檎吒淖儠r(shí)您只需要編寫一個(gè)新的Java類,并將其在服務(wù)器主機(jī)上安裝一次即可。

(3)設(shè)計(jì)方式。對(duì)象傳遞功能使您可以在分布式計(jì)算中充分利用面向?qū)ο蠹夹g(shù)的強(qiáng)大功能,如二層和三層結(jié)構(gòu)系統(tǒng)。如果對(duì)象能夠傳遞屬性,那么就可以在解決方案中使用面向?qū)ο蟮脑O(shè)計(jì)方式。所有面向?qū)ο蟮脑O(shè)計(jì)方式無(wú)不依靠不同的屬性來(lái)發(fā)揮功能,如果不能傳遞完整的對(duì)象(包括實(shí)現(xiàn)和類型),就會(huì)失去設(shè)計(jì)方式上所提供的優(yōu)點(diǎn)。

(4)安全性。RMI使用Java內(nèi)置的安全機(jī)制保證下載執(zhí)行程序時(shí)用戶系統(tǒng)的安全。RMI使用專門為保護(hù)系統(tǒng)免遭惡意小應(yīng)用程序侵害而設(shè)計(jì)的安全管理程序,可保護(hù)您的系統(tǒng)和網(wǎng)絡(luò)免遭潛在的惡意下載程序的破壞。在情況嚴(yán)重時(shí),服務(wù)器可拒絕下載任何執(zhí)行程序。

(5)便于編寫和使用。RMI使得Java遠(yuǎn)程服務(wù)程序和訪問(wèn)這些服務(wù)程序的Java客戶程序的編寫工作變得輕松、簡(jiǎn)單。遠(yuǎn)程接口實(shí)際上就是Java接口。服務(wù)程序大約用三行指令聲明其本身是服務(wù)程序,其他方面則與Java對(duì)象類似。這種方法便于快速編寫完整的分布式對(duì)象系統(tǒng)的服務(wù)程序,并快速地制做軟件的原型和早期版本,以便于進(jìn)行測(cè)試和評(píng)估。RMI程序編寫簡(jiǎn)單,維護(hù)簡(jiǎn)便。

(6)可連接現(xiàn)有/原有的系統(tǒng)。RMI可通過(guò)Java的本機(jī)方法接口JNI與現(xiàn)有系統(tǒng)進(jìn)行進(jìn)行交互。利用RMI和JNI,您就能用Java語(yǔ)言編寫客戶端程序,還能使用現(xiàn)有的服務(wù)器端程序。在使用RMI/JNI與現(xiàn)有服務(wù)器連接時(shí),您可以有選擇地用Java重新編寫服務(wù)程序的任何部分,并使新的程序充分發(fā)揮Java的功能。類似地,RMI可利用JDBC、在不修改使用數(shù)據(jù)庫(kù)的現(xiàn)有非Java源代碼的前提下與現(xiàn)有關(guān)系數(shù)據(jù)庫(kù)進(jìn)行交互。

(7)編寫一次,到處運(yùn)行。RMI是Java“編寫一次,到處運(yùn)行”方法的一部分。任何基于RMI的系統(tǒng)均可100%地移植到任何Java虛擬機(jī)上,RMI/JDBC系統(tǒng)也不例外。如果使用RMI/JNI與現(xiàn)有系統(tǒng)進(jìn)行交互工作,則采用JNI編寫的代碼可在任何Java虛擬機(jī)進(jìn)行編譯、運(yùn)行。

(8)分布式垃圾收集。RMI采用分布式垃圾收集功能收集不再被網(wǎng)絡(luò)中任何客戶程序所引用的遠(yuǎn)程服務(wù)對(duì)象。與Java虛擬機(jī)內(nèi)部的垃圾收集類似,分布式垃圾收集功能允許用戶根據(jù)自己的需要定義服務(wù)器對(duì)象,并且明確這些對(duì)象在不被客戶機(jī)引用時(shí)會(huì)刪除。

(9)并行計(jì)算。RMI采用多線程處理方法,可使服務(wù)器利用這些Java線程更好地并行處理客戶端的請(qǐng)求。Java分布式計(jì)算解決方案:RMI從JDK1.1開(kāi)始就是Java平臺(tái)的核心部分,因此,它存在于任何一臺(tái)1.1Java虛擬機(jī)中。所有RMI系統(tǒng)均采用相同的公開(kāi)協(xié)議,所以,所有Java系統(tǒng)均可直接相互對(duì)話,而不必事先對(duì)協(xié)議進(jìn)行轉(zhuǎn)換。

9.2RMI工作機(jī)制

RMI應(yīng)用程序通常包括兩個(gè)獨(dú)立的程序,即服務(wù)器端程序和客戶機(jī)端程序。典型的服務(wù)器應(yīng)用程序?qū)?chuàng)建多個(gè)遠(yuǎn)程對(duì)象,使這些遠(yuǎn)程對(duì)象能夠被引用,然后等待客戶機(jī)調(diào)用這些遠(yuǎn)程對(duì)象的方法。而典型的客戶機(jī)程序則從服務(wù)器中得到一個(gè)或多個(gè)遠(yuǎn)程對(duì)象的引用,然后調(diào)用遠(yuǎn)程對(duì)象的方法。RMI為服務(wù)器和客戶機(jī)進(jìn)行通信和信息傳遞提供了一種機(jī)制。

RMI為服務(wù)器和客戶機(jī)進(jìn)行遠(yuǎn)程通信和信息傳遞提供了一種標(biāo)準(zhǔn)機(jī)制,即樁(stub)和構(gòu)架(skeleton)。其中,遠(yuǎn)程對(duì)象的stub擔(dān)當(dāng)遠(yuǎn)程對(duì)象的客戶本地代表或代理人角色。調(diào)用程序?qū)⒄{(diào)用本地stub的方法,而本地stub將負(fù)責(zé)執(zhí)行對(duì)遠(yuǎn)程對(duì)象的方法調(diào)用。stub通常負(fù)責(zé)初始化遠(yuǎn)程調(diào)用、序列化、遠(yuǎn)程方法調(diào)用、反序列化、遠(yuǎn)程方法調(diào)用完成處理等。遠(yuǎn)程對(duì)象的stub與該遠(yuǎn)程對(duì)象所實(shí)現(xiàn)的遠(yuǎn)程接口集相同。調(diào)用stub的方法時(shí)將執(zhí)行下列操作:

●?初始化與包含遠(yuǎn)程對(duì)象的遠(yuǎn)程虛擬機(jī)的連接;

●?對(duì)遠(yuǎn)程虛擬機(jī)的參數(shù)進(jìn)行編組(寫入并傳輸);●?等待方法調(diào)用結(jié)果;

●?解編(讀取)返回值或返回的異常;

●?將值返回給調(diào)用程序。

為了向調(diào)用程序展示比較簡(jiǎn)單的調(diào)用機(jī)制,stub將參數(shù)的序列化和網(wǎng)絡(luò)級(jí)通信等細(xì)節(jié)隱藏了起來(lái)。

在遠(yuǎn)程虛擬機(jī)中,每個(gè)遠(yuǎn)程對(duì)象都可以有相應(yīng)的架構(gòu)(在JDK1.2環(huán)境中無(wú)需使用架構(gòu))。架構(gòu)負(fù)責(zé)將調(diào)用分配給實(shí)際的遠(yuǎn)程對(duì)象實(shí)現(xiàn)(反序列化)、反序列化客戶端參數(shù)、調(diào)用實(shí)際遠(yuǎn)程對(duì)象、序列化返回客戶端參數(shù)。它在接收方法調(diào)用時(shí)執(zhí)行下列操作:

●?解編(讀取)遠(yuǎn)程方法的參數(shù);●?調(diào)用實(shí)際遠(yuǎn)程對(duì)象實(shí)現(xiàn)上的方法;

●?將結(jié)果(返回值或異常)編組(寫入并傳輸)給調(diào)用程序。

樁和架構(gòu)是應(yīng)用程序與系統(tǒng)其他部分的接口,通常使用RMI的rmic編譯器產(chǎn)生。

RMI系統(tǒng)結(jié)構(gòu)由以下三個(gè)部分組成:

●?樁/構(gòu)架層:應(yīng)用程序與系統(tǒng)其他部分的接口;

●?遠(yuǎn)程引用層:負(fù)責(zé)獨(dú)立于客戶樁和服務(wù)器構(gòu)架,提供多種形式的遠(yuǎn)程引用和調(diào)用協(xié)議;

●?傳輸層:低級(jí)層,在不同的地址空間內(nèi)傳輸序列化的流。

RMI工作機(jī)制為:調(diào)用通過(guò)樁/構(gòu)架層傳遞,它們作為應(yīng)用程序與RMI系統(tǒng)其他部分的一個(gè)接口來(lái)提供服務(wù),其唯一目的是通過(guò)序列化流,傳輸數(shù)據(jù)到遠(yuǎn)程引用層;一旦數(shù)據(jù)通過(guò)樁/構(gòu)架層傳遞,它將通過(guò)遠(yuǎn)程引用層實(shí)現(xiàn)調(diào)用,并且使用面向連接的流,將數(shù)據(jù)傳遞到傳輸層;當(dāng)數(shù)據(jù)到達(dá),傳輸層負(fù)責(zé)建立連接并管理這些連接。RMI系統(tǒng)的結(jié)構(gòu)如圖9-2所示。圖9-2RMI系統(tǒng)結(jié)構(gòu)遠(yuǎn)程方法調(diào)用的流向?yàn)椋簭目蛻魧?duì)象經(jīng)樁程序、遠(yuǎn)程引用層(RemoteReferenceLayer)和傳輸層(TransportLayer)向下,傳遞給主機(jī),然后再次經(jīng)傳輸層,向上穿過(guò)遠(yuǎn)程調(diào)用層和骨干網(wǎng)(Skeleton),到達(dá)服務(wù)器對(duì)象,如圖9-2中虛線流向。

在RMI系統(tǒng)結(jié)構(gòu)中,樁程序扮演著遠(yuǎn)程服務(wù)器對(duì)象的代理的角色,使該對(duì)象可被客戶激活。遠(yuǎn)程引用層處理語(yǔ)義,管理單一或多重對(duì)象的通信,決定調(diào)用是發(fā)往一個(gè)服務(wù)器還是多個(gè)。傳輸層管理實(shí)際的連接,并且追蹤可以接受方法調(diào)用的遠(yuǎn)程對(duì)象。服務(wù)器端的骨干網(wǎng)完成對(duì)服務(wù)器對(duì)象實(shí)際的方法調(diào)用,并獲取返回值。返回值向下經(jīng)遠(yuǎn)程引用層、服務(wù)器端的傳輸層傳遞回客戶端,再向上經(jīng)傳輸層和遠(yuǎn)程調(diào)用層返回。最后,樁程序獲得返回值。典型的服務(wù)器應(yīng)用程序?qū)?chuàng)建多個(gè)遠(yuǎn)程對(duì)象,并使這些遠(yuǎn)程對(duì)象能夠被引用,然后等待客戶機(jī)調(diào)用這些遠(yuǎn)程對(duì)象提供的方法。典型的客戶機(jī)程序則從服務(wù)器中得到一個(gè)或多個(gè)遠(yuǎn)程對(duì)象的引用,然后調(diào)用遠(yuǎn)程對(duì)象的方法。

9.3RMI實(shí)現(xiàn)技術(shù)

9.3.1RMI類和工具

利用RMI編寫分布式對(duì)象應(yīng)用程序需要五個(gè)類庫(kù)包和三個(gè)應(yīng)用軟件工具。其中,五個(gè)類庫(kù)包分別是:

java.rmi,提供客戶端的RMI類、接口和異常類;

java.rmi.server,提供服務(wù)器端的RMI類,接口和異常類;

java.rmi.registry,用于管理RMI命名服務(wù)的類;

java.rmi.dgc,用于管理分布式垃圾收集(Distributional

GarbageCollection)的類;

java.rmi.activation,用于按需激活的RMI服務(wù)的類。三個(gè)應(yīng)用軟件工具均包含在JSDK安裝路徑的bin目錄下,分別是:

rmic.exe,它是RMI編譯器,在使用javac編譯java源程序后,還需要使用rmic編譯服務(wù)器端的class文件,用于生成stub和skeleton;

rmiregistry.exe,一個(gè)為RMI提供命名服務(wù)的服務(wù)器,這項(xiàng)服務(wù)把名字和對(duì)象關(guān)聯(lián)在一起,即將RMI服務(wù)注冊(cè)為一個(gè)遠(yuǎn)程對(duì)象以便客戶端的調(diào)用;

rmi.exe,一個(gè)支持RMI激活框架的服務(wù)器。9.3.2RMI實(shí)現(xiàn)流程

因?yàn)镽MI允許調(diào)用程序?qū)⒓僇ava對(duì)象傳給遠(yuǎn)程對(duì)象,所以RMI將提供必要的機(jī)制,既可以加載對(duì)象的代碼又可以傳輸對(duì)象的數(shù)據(jù)。在RMI分布式應(yīng)用程序運(yùn)行時(shí),服務(wù)器調(diào)用注冊(cè)服務(wù)程序以使名字與遠(yuǎn)程對(duì)象相關(guān)聯(lián)??蛻魴C(jī)在服務(wù)器上的注冊(cè)服務(wù)程序中用遠(yuǎn)程對(duì)象的名字查找該遠(yuǎn)程對(duì)象,然后調(diào)用它的方法。利用RMI編寫分布式對(duì)象應(yīng)用程序需要完成以下工作:

●?定位遠(yuǎn)程對(duì)象。應(yīng)用程序可使用兩種機(jī)制中的一種得到對(duì)遠(yuǎn)程對(duì)象的引用。它既可用RMI的簡(jiǎn)單命名工具rmiregistry來(lái)注冊(cè)它的遠(yuǎn)程對(duì)象,也可以將遠(yuǎn)程對(duì)象引用作為常規(guī)操作的一部分來(lái)進(jìn)行傳遞和返回?!?與遠(yuǎn)程對(duì)象通信。遠(yuǎn)程對(duì)象間通信的細(xì)節(jié)由RMI處理,對(duì)于程序員來(lái)說(shuō),遠(yuǎn)程通信看起來(lái)就像標(biāo)準(zhǔn)的Java方法調(diào)用。

●?給作為參數(shù)或返回值傳遞的對(duì)象加載類字節(jié)碼。

為了實(shí)現(xiàn)以上工作,RMI實(shí)現(xiàn)的步驟如下:

(1)定義遠(yuǎn)程服務(wù)接口,該接口必須聲明為public,必須繼承java.rmi.Remote接口。在接口定義中說(shuō)明服務(wù)器提供的方法特性,包含了方法的名字和參數(shù),這個(gè)服務(wù)方法必須拋出異常java.rmi.RemoteException;

(2)實(shí)現(xiàn)遠(yuǎn)程服務(wù)接口所定義的方法;

(3)利用rmic生成樁和框架文件;

(4)一個(gè)運(yùn)行遠(yuǎn)程服務(wù)的服務(wù)器;

(5)一個(gè)RMI命名服務(wù),它允許客戶端去發(fā)現(xiàn)這個(gè)遠(yuǎn)程服務(wù);

(6)注冊(cè)遠(yuǎn)程對(duì)象;

(7)類文件的提供者(一個(gè)HTTP或者FTP服務(wù)器);

(8)一個(gè)需要這個(gè)遠(yuǎn)程服務(wù)的客戶端程序。

【例9-1】定義遠(yuǎn)程服務(wù)接口,一個(gè)用于數(shù)組相加的遠(yuǎn)程服務(wù)接口。

1.importjava.rmi.*;

2.publicinterfaceArithextendsjava.rmi.Remote{

3.int[]add(inta[],intb[])throwsjava.rmi.RemoteException;

}

代碼注釋如下:

①第1行引用了重要的RMI類庫(kù)包;

②第2行定義了自定義的遠(yuǎn)程接口Arith,該接口必須具有公開(kāi)(public)屬性,而且繼承了java.rmi.Remote接口;

③第3行申明一個(gè)沒(méi)有方法體的add(),并且該方法拋出了java.rmi.RemoteException異常。

代碼注釋如下:

①第1~2行引用重要類庫(kù)包和類;

②第3行定義遠(yuǎn)程服務(wù)類ArithImp1,它實(shí)現(xiàn)了事先定義遠(yuǎn)程服務(wù)接口Arith,并且繼承了UnicastRemoteObject類,用于遠(yuǎn)程單播傳輸對(duì)象;

③第4行定義成員屬性,用于存儲(chǔ)該遠(yuǎn)程服務(wù)的名稱;

④第5~8行定義構(gòu)造方法,通過(guò)super()指定本遠(yuǎn)程服務(wù)的名稱;

⑤第9~14行覆蓋了Arith接口的add()方法,實(shí)現(xiàn)了數(shù)組相加功能;⑥第16~17行定義RMI安全管理器實(shí)例,并加入到系統(tǒng)的安全管理器中;

⑦第18~24行創(chuàng)建遠(yuǎn)程對(duì)象的對(duì)象實(shí)例名稱為obj,通過(guò)rebind()注冊(cè)了遠(yuǎn)程服務(wù)名稱ArithServer,將該服務(wù)綁定在“//localhost:3000/ArithServer”,使本地環(huán)回測(cè)試用戶可用。

該程序僅說(shuō)明遠(yuǎn)程服務(wù)的內(nèi)容,運(yùn)行該服務(wù)還需要特殊的指令。

客戶端是調(diào)用服務(wù)的,它提供用于服務(wù)的數(shù)據(jù)和獲得服務(wù)結(jié)果,如例9-3提供了兩個(gè)準(zhǔn)備相加的數(shù)組。

代碼注釋如下:

①第1~2行引用重要的類庫(kù)包;

②第5~7行給出了用于服務(wù)的兩個(gè)數(shù)組a[]?和b[]?以及用于存儲(chǔ)結(jié)果的數(shù)組result[];

③第9行查找在遠(yuǎn)程服務(wù)器localhost端口3000上開(kāi)放的注冊(cè)服務(wù)ArithServer,并生成遠(yuǎn)程引用對(duì)象obj;

④第10行調(diào)用遠(yuǎn)程方法調(diào)用和傳遞參數(shù);

⑤第14~17行輸出結(jié)果。

在第4章中,曾經(jīng)提到使用多線程實(shí)現(xiàn)累加計(jì)數(shù)器,現(xiàn)在將它修改為采用RMI完成數(shù)值的累加。其不同之處在于,原程序在一臺(tái)計(jì)算機(jī)上啟動(dòng)多個(gè)線程共同完成累加任務(wù),現(xiàn)在變更為由多臺(tái)計(jì)算機(jī)同時(shí)完成累加任務(wù)。為了使觀察效果更好,將累加范圍改為1~10?000,并設(shè)置了計(jì)時(shí)器,通過(guò)計(jì)算所消耗時(shí)間來(lái)判斷是否得到優(yōu)化。

【例9-4】數(shù)字累加累計(jì)接口。

1.

importjava.rmi.*;

2.publicinterfaceSumextendsjava.rmi.Remote{

3.intadd(intstart,intend)throwsjava.rmi.RemoteException;

4.}

代碼注釋如下:

①第2行定義遠(yuǎn)程服務(wù)接口Arith,其繼承了java.rmi.Remote接口;

②第3行申明了遠(yuǎn)程服務(wù)方法,其參數(shù)是用于累加數(shù)值的區(qū)間。

【例9-5】實(shí)現(xiàn)遠(yuǎn)程服務(wù),實(shí)現(xiàn)累加服務(wù),注意運(yùn)行在兩臺(tái)不同的服務(wù)器上,供客戶端調(diào)用。

代碼注釋如下:

①第1~2行引用重要類庫(kù)包和類;

②第3行定義遠(yuǎn)程服務(wù)類SumImp,它實(shí)現(xiàn)了事先定義遠(yuǎn)程服務(wù)接口Sum,并且繼承了UnicastRemoteObject類,用于遠(yuǎn)程單播傳輸對(duì)象;

③第4行定義成員屬性,用于存儲(chǔ)該遠(yuǎn)程服務(wù)的名稱;

④第5~8行定義構(gòu)造方法,通過(guò)super()?指定本遠(yuǎn)程服務(wù)的名稱;

⑤第9~14行覆蓋了Sum接口的add()?方法,實(shí)現(xiàn)了數(shù)組相加功能;⑥第16~17行定義RMI安全管理器實(shí)例,并加入到系統(tǒng)的安全管理器中;

⑦第18~24行創(chuàng)建遠(yuǎn)程對(duì)象的對(duì)象實(shí)例名稱為obj,通過(guò)rebind()注冊(cè)了遠(yuǎn)程服務(wù)名稱SumServer,將該服務(wù)綁定在“//服務(wù)運(yùn)行的地址:3000/SumServer”,該服務(wù)運(yùn)行的地址需要根據(jù)運(yùn)行環(huán)境獲得。

【例9-6】客戶端將一個(gè)1~10000的累加工作分配到兩個(gè)遠(yuǎn)程服務(wù)器上。

代碼注釋如下:

①第1~2行引用重要的類庫(kù);

②第3行定義客戶端類,其實(shí)現(xiàn)了Runnable接口;

③第4~11行定義了累加數(shù)值的區(qū)間start和end,累加和sum和遠(yuǎn)程服務(wù)名稱server;

④第12~19行實(shí)現(xiàn)線程運(yùn)行入口,在指定的服務(wù)器上查找服務(wù)Naming.loop(server),如找到,則調(diào)用遠(yuǎn)程方法obj.add(start,end);

⑤第24~25行自定義兩個(gè)線程對(duì)象,帶入?yún)?shù),指定數(shù)值累加區(qū)間和遠(yuǎn)程服務(wù)名稱;

⑥第28~29,31行啟動(dòng)線程;

⑦第28、31、33行用于記錄累加所用的時(shí)間;

⑧第30行將這兩個(gè)子線程添加到主線程中,保證子線程先于主線程結(jié)束。9.3.3RMI運(yùn)行步驟

由于RMI程序的運(yùn)行依賴于網(wǎng)絡(luò)的遠(yuǎn)程調(diào)用,它涉及安全問(wèn)題,因而不同于普通的JavaApplication程序,其運(yùn)行一共分為五步:

(1)使用javac*.java分別編譯接口程序、服務(wù)端程序和客戶端程序。

(2)使用rmic服務(wù)端的?.class文件,產(chǎn)生一個(gè)服務(wù)端的_Stub.class的產(chǎn)生樁和框架文件。樁和框架在服務(wù)器端運(yùn)行時(shí)確定,根據(jù)需要?jiǎng)討B(tài)裝載,采用rmic編譯器生成stub和skeleton。例如:rmicrmiExampl,在JDK1.5下,該命令執(zhí)行后將生成一個(gè)樁文件,文件名為rmiExampl_Stub.class。

(3)使用startrmiregistry,在服務(wù)端啟動(dòng)一個(gè)RMI注冊(cè)表,便于對(duì)服務(wù)端提供的遠(yuǎn)程服務(wù)進(jìn)行注冊(cè);RMI注冊(cè)表是一個(gè)名字服務(wù),允許客戶程序獲得對(duì)遠(yuǎn)程對(duì)象的引用,在服務(wù)器/客戶程序之前,必須啟動(dòng)RMI注冊(cè)表。啟動(dòng)方式:

startrmiregistry

默認(rèn)情況下,啟動(dòng)的端口為1099。如果要改變端口則使用

startrmiregistry3000

(4)執(zhí)行服務(wù)端和客戶端程序,應(yīng)首先在服務(wù)端按安全策略文件運(yùn)行服務(wù)器,輸入

java-Djava.security.policy=policyNameserverName

(5)在客戶端按安全策略文件運(yùn)行客戶端,輸入

java-Djava.security.policy=policyNameclientName

注意,有的時(shí)候要在后面加上參數(shù)localhost。

在運(yùn)行時(shí),有可能出現(xiàn)如圖9-3所示的提示。圖9-3RMI服務(wù)端運(yùn)行提示該提示中提到程序運(yùn)行中出現(xiàn)了訪問(wèn)控制異常(AccessControlException),對(duì)地址3000端口的連接和解析服務(wù)訪問(wèn)被拒絕。出現(xiàn)該異常則說(shuō)明程序運(yùn)行還缺少策略文件。9.3.4策略文件

RMI程序是一個(gè)調(diào)用分布式資源的網(wǎng)絡(luò)程序,運(yùn)行客戶端通過(guò)服務(wù)端的指定的端口訪問(wèn)資源,需要控制的安全機(jī)制來(lái)保護(hù)服務(wù)端。在RMI中利用策略文件,對(duì)計(jì)算機(jī)端口的訪問(wèn)進(jìn)行某些設(shè)置。

策略文件是一個(gè)文本文件,里面記錄了一些對(duì)計(jì)算機(jī)資源訪問(wèn)的方式,比如對(duì)本地文件的訪問(wèn)控制,對(duì)端口的訪問(wèn)控制等。其文件后綴名為“*.policy”。在Windows系

溫馨提示

  • 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)論