版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第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ī)上的對象互相調(diào)用?!备鞣N分布式系統(tǒng)都有自己的調(diào)用協(xié)議,著名的解決方案有:
●?公共對象請求代理體系結(jié)構(gòu)(CommonObjectRequestBrokerArchitecture,CORBA)的IIOP(InternetInterORBProtocol,互聯(lián)網(wǎng)內(nèi)部對象請求代理協(xié)議)。CORBA體系結(jié)構(gòu)是對象管理組織(ObjectManagermentGroup,OMG)為解決分布式處理環(huán)境(DistributedComputingEnviornment,DCE)中,硬件和軟件系統(tǒng)的互連而提出的一種解決方案?!?微軟事務(wù)服務(wù)器(MicrosoftTransactionServer,MTS)中的分布式組件對象模型(DistributedComponentObjectModel,DCOM)。DCOM是一系列微軟的概念和程序接口,利用這個接口,客戶端程序?qū)ο竽軌蛘埱髞碜跃W(wǎng)絡(luò)中另一臺計(jì)算機(jī)上的服務(wù)器程序?qū)ο蟆?/p>
●?RMI。RMI是Java的一組開發(fā)分布式應(yīng)用程序的API。RMI使用Java語言接口定義了遠(yuǎn)程對象,它集合了Java序列化和Java遠(yuǎn)程方法協(xié)議(JavaRemoteMethodProtocol)。它是一種機(jī)制,能夠讓在某個Java虛擬機(jī)上的對象調(diào)用另一個Java虛擬機(jī)中對象上的方法,可以調(diào)用任何實(shí)現(xiàn)該遠(yuǎn)程接口的對象。
Java語言之所以被稱為網(wǎng)絡(luò)開發(fā)語言,因?yàn)樗婚_始就與Web開發(fā)聯(lián)系在一起,并擁有“強(qiáng)大開發(fā)分布式網(wǎng)絡(luò)應(yīng)用”的能力,RMI就是開發(fā)百分之百純Java的網(wǎng)絡(luò)分布式應(yīng)用系統(tǒng)的核心解決方案之一。
RMI是Java在JDK1.1中實(shí)現(xiàn)的,是非常重要的底層技術(shù),它大大增強(qiáng)了Java開發(fā)分布式應(yīng)用的能力。EJB(EnterpriseJavaBean)就是建立在RMI基礎(chǔ)之上的,現(xiàn)在還有一些開源的遠(yuǎn)程調(diào)用組件,其底層技術(shù)也采用了RMI。
RMI使用Java語言接口定義了遠(yuǎn)程對象,它集合了Java序列化和Java遠(yuǎn)程方法協(xié)議(JavaRemoteMethodProtocol)。簡單地說,這樣使原先的程序由在同一操作系統(tǒng)的方法調(diào)用,變成了在不同操作系統(tǒng)之間程序的方法調(diào)用。由于J2EE是分布式程序平臺,因而RMI機(jī)制可實(shí)現(xiàn)程序組件在不同操作系統(tǒng)之間的通信。比如,一個EJB可以通過RMI調(diào)用Web上另一臺機(jī)器上的EJB遠(yuǎn)程方法,即跨平臺操作,如圖9-1所示。圖9-1RMI工作原理
RMI以Java為核心,它將Java的安全性和可移植性等強(qiáng)大功能帶給了分布式計(jì)算,所以可將代理和業(yè)務(wù)邏輯等屬性移動到網(wǎng)絡(luò)中最合適的地方,例如遠(yuǎn)程的服務(wù)器。RMI可以被看做是遠(yuǎn)程過程控制(RemoteProcessControl,RPC)的Java版本,但是傳統(tǒng)的RPC并不能很好地應(yīng)用于分布式對象系統(tǒng)。而RMI則支持存儲于不同地址空間的程序級對象之間彼此進(jìn)行通信,實(shí)現(xiàn)遠(yuǎn)程對象之間的無縫遠(yuǎn)程調(diào)用。
在Java的RMI規(guī)范中提供的功能有:
●?支持對存在于不同虛擬機(jī)上的對象進(jìn)行無縫的遠(yuǎn)程調(diào)用;●?支持服務(wù)器對客戶的回調(diào);
●?把分布式對象模型自然地集成到Java語言里,盡可能從語義上保留Java的面向?qū)ο蟮奶卣鳎?/p>
●?使分布式對象模型和本地Java對象模型間的差異明朗;
●?使編寫可靠的分布式應(yīng)用程序盡可能簡單;
●?保留Javarun-time環(huán)境所提供的安全性;
●?多樣化的遠(yuǎn)程調(diào)用機(jī)制;
●?支持多點(diǎn)傳輸?shù)哪芰Γ?/p>
●?支持分布式的垃圾回收。9.1.2RMI的優(yōu)點(diǎn)
RMI為采用Java對象的分布式計(jì)算提供了簡單而直接的途徑,通過RMI技術(shù)充分體現(xiàn)了“編寫一次就能在任何地方運(yùn)行的模式”。RMI可利用標(biāo)準(zhǔn)Java本機(jī)方法接口JNI與現(xiàn)有的和原有的系統(tǒng)相連接。RMI還可利用標(biāo)準(zhǔn)JDBC類庫與關(guān)系型數(shù)據(jù)庫連接,即RMI/JNI和RMI/JDBC相結(jié)合,并且可利用RMI與目前使用非Java語言的現(xiàn)有服務(wù)器進(jìn)行通信。
RMI的主要優(yōu)點(diǎn)如下:
(1)面向?qū)ο?。RMI可將完整的對象作為參數(shù)和返回值進(jìn)行傳遞,而不僅僅是預(yù)定義的數(shù)據(jù)類型。也就是說,您可以將類似Java哈希表這樣的復(fù)雜類型作為一個參數(shù)進(jìn)行傳遞。而在目前的RPC系統(tǒng)中,您只能依靠客戶機(jī)將此類對象分解成基本數(shù)據(jù)類型,然后傳遞這些數(shù)據(jù)類型,最后在服務(wù)器端重新創(chuàng)建哈希表。RMI則不需額外的客戶程序代碼(將對象分解成基本數(shù)據(jù)類型),直接跨網(wǎng)傳遞對象。
(2)可移動屬性。RMI可將屬性(類實(shí)現(xiàn)程序)從客戶機(jī)移動到服務(wù)器,或者從服務(wù)器移到客戶機(jī)。例如,可以定義一個檢查雇員開支報(bào)告的接口,以便察看雇員是否遵守了公司目前實(shí)行的政策。在開支報(bào)告創(chuàng)建后,客戶機(jī)就會從服務(wù)器端獲得實(shí)現(xiàn)該接口的對象。如果政策發(fā)生變化,服務(wù)器端就會開始返回使用了新政策的該接口的另一個實(shí)現(xiàn)程序。不必在用戶系統(tǒng)上安裝任何新的軟件就能在客戶端檢查限制條件,從而向用戶提供快速的反饋,并降低服務(wù)器的工作量。這樣程序就能具備最大的靈活性,因?yàn)檎吒淖儠r您只需要編寫一個新的Java類,并將其在服務(wù)器主機(jī)上安裝一次即可。
(3)設(shè)計(jì)方式。對象傳遞功能使您可以在分布式計(jì)算中充分利用面向?qū)ο蠹夹g(shù)的強(qiáng)大功能,如二層和三層結(jié)構(gòu)系統(tǒng)。如果對象能夠傳遞屬性,那么就可以在解決方案中使用面向?qū)ο蟮脑O(shè)計(jì)方式。所有面向?qū)ο蟮脑O(shè)計(jì)方式無不依靠不同的屬性來發(fā)揮功能,如果不能傳遞完整的對象(包括實(shí)現(xiàn)和類型),就會失去設(shè)計(jì)方式上所提供的優(yōu)點(diǎn)。
(4)安全性。RMI使用Java內(nèi)置的安全機(jī)制保證下載執(zhí)行程序時用戶系統(tǒng)的安全。RMI使用專門為保護(hù)系統(tǒng)免遭惡意小應(yīng)用程序侵害而設(shè)計(jì)的安全管理程序,可保護(hù)您的系統(tǒng)和網(wǎng)絡(luò)免遭潛在的惡意下載程序的破壞。在情況嚴(yán)重時,服務(wù)器可拒絕下載任何執(zhí)行程序。
(5)便于編寫和使用。RMI使得Java遠(yuǎn)程服務(wù)程序和訪問這些服務(wù)程序的Java客戶程序的編寫工作變得輕松、簡單。遠(yuǎn)程接口實(shí)際上就是Java接口。服務(wù)程序大約用三行指令聲明其本身是服務(wù)程序,其他方面則與Java對象類似。這種方法便于快速編寫完整的分布式對象系統(tǒng)的服務(wù)程序,并快速地制做軟件的原型和早期版本,以便于進(jìn)行測試和評估。RMI程序編寫簡單,維護(hù)簡便。
(6)可連接現(xiàn)有/原有的系統(tǒng)。RMI可通過Java的本機(jī)方法接口JNI與現(xiàn)有系統(tǒng)進(jìn)行進(jìn)行交互。利用RMI和JNI,您就能用Java語言編寫客戶端程序,還能使用現(xiàn)有的服務(wù)器端程序。在使用RMI/JNI與現(xiàn)有服務(wù)器連接時,您可以有選擇地用Java重新編寫服務(wù)程序的任何部分,并使新的程序充分發(fā)揮Java的功能。類似地,RMI可利用JDBC、在不修改使用數(shù)據(jù)庫的現(xiàn)有非Java源代碼的前提下與現(xiàn)有關(guān)系數(shù)據(jù)庫進(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ù)對象。與Java虛擬機(jī)內(nèi)部的垃圾收集類似,分布式垃圾收集功能允許用戶根據(jù)自己的需要定義服務(wù)器對象,并且明確這些對象在不被客戶機(jī)引用時會刪除。
(9)并行計(jì)算。RMI采用多線程處理方法,可使服務(wù)器利用這些Java線程更好地并行處理客戶端的請求。Java分布式計(jì)算解決方案:RMI從JDK1.1開始就是Java平臺的核心部分,因此,它存在于任何一臺1.1Java虛擬機(jī)中。所有RMI系統(tǒng)均采用相同的公開協(xié)議,所以,所有Java系統(tǒng)均可直接相互對話,而不必事先對協(xié)議進(jìn)行轉(zhuǎn)換。
9.2RMI工作機(jī)制
RMI應(yīng)用程序通常包括兩個獨(dú)立的程序,即服務(wù)器端程序和客戶機(jī)端程序。典型的服務(wù)器應(yīng)用程序?qū)?chuàng)建多個遠(yuǎn)程對象,使這些遠(yuǎn)程對象能夠被引用,然后等待客戶機(jī)調(diào)用這些遠(yuǎn)程對象的方法。而典型的客戶機(jī)程序則從服務(wù)器中得到一個或多個遠(yuǎn)程對象的引用,然后調(diào)用遠(yuǎn)程對象的方法。RMI為服務(wù)器和客戶機(jī)進(jìn)行通信和信息傳遞提供了一種機(jī)制。
RMI為服務(wù)器和客戶機(jī)進(jìn)行遠(yuǎn)程通信和信息傳遞提供了一種標(biāo)準(zhǔn)機(jī)制,即樁(stub)和構(gòu)架(skeleton)。其中,遠(yuǎn)程對象的stub擔(dān)當(dāng)遠(yuǎn)程對象的客戶本地代表或代理人角色。調(diào)用程序?qū)⒄{(diào)用本地stub的方法,而本地stub將負(fù)責(zé)執(zhí)行對遠(yuǎn)程對象的方法調(diào)用。stub通常負(fù)責(zé)初始化遠(yuǎn)程調(diào)用、序列化、遠(yuǎn)程方法調(diào)用、反序列化、遠(yuǎn)程方法調(diào)用完成處理等。遠(yuǎn)程對象的stub與該遠(yuǎn)程對象所實(shí)現(xiàn)的遠(yuǎn)程接口集相同。調(diào)用stub的方法時將執(zhí)行下列操作:
●?初始化與包含遠(yuǎn)程對象的遠(yuǎn)程虛擬機(jī)的連接;
●?對遠(yuǎn)程虛擬機(jī)的參數(shù)進(jìn)行編組(寫入并傳輸);●?等待方法調(diào)用結(jié)果;
●?解編(讀取)返回值或返回的異常;
●?將值返回給調(diào)用程序。
為了向調(diào)用程序展示比較簡單的調(diào)用機(jī)制,stub將參數(shù)的序列化和網(wǎng)絡(luò)級通信等細(xì)節(jié)隱藏了起來。
在遠(yuǎn)程虛擬機(jī)中,每個遠(yuǎn)程對象都可以有相應(yīng)的架構(gòu)(在JDK1.2環(huán)境中無需使用架構(gòu))。架構(gòu)負(fù)責(zé)將調(diào)用分配給實(shí)際的遠(yuǎn)程對象實(shí)現(xiàn)(反序列化)、反序列化客戶端參數(shù)、調(diào)用實(shí)際遠(yuǎn)程對象、序列化返回客戶端參數(shù)。它在接收方法調(diào)用時執(zhí)行下列操作:
●?解編(讀取)遠(yuǎn)程方法的參數(shù);●?調(diào)用實(shí)際遠(yuǎn)程對象實(shí)現(xiàn)上的方法;
●?將結(jié)果(返回值或異常)編組(寫入并傳輸)給調(diào)用程序。
樁和架構(gòu)是應(yīng)用程序與系統(tǒng)其他部分的接口,通常使用RMI的rmic編譯器產(chǎn)生。
RMI系統(tǒng)結(jié)構(gòu)由以下三個部分組成:
●?樁/構(gòu)架層:應(yīng)用程序與系統(tǒng)其他部分的接口;
●?遠(yuǎn)程引用層:負(fù)責(zé)獨(dú)立于客戶樁和服務(wù)器構(gòu)架,提供多種形式的遠(yuǎn)程引用和調(diào)用協(xié)議;
●?傳輸層:低級層,在不同的地址空間內(nèi)傳輸序列化的流。
RMI工作機(jī)制為:調(diào)用通過樁/構(gòu)架層傳遞,它們作為應(yīng)用程序與RMI系統(tǒng)其他部分的一個接口來提供服務(wù),其唯一目的是通過序列化流,傳輸數(shù)據(jù)到遠(yuǎn)程引用層;一旦數(shù)據(jù)通過樁/構(gòu)架層傳遞,它將通過遠(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)椋簭目蛻魧ο蠼?jīng)樁程序、遠(yuǎn)程引用層(RemoteReferenceLayer)和傳輸層(TransportLayer)向下,傳遞給主機(jī),然后再次經(jīng)傳輸層,向上穿過遠(yuǎn)程調(diào)用層和骨干網(wǎng)(Skeleton),到達(dá)服務(wù)器對象,如圖9-2中虛線流向。
在RMI系統(tǒng)結(jié)構(gòu)中,樁程序扮演著遠(yuǎn)程服務(wù)器對象的代理的角色,使該對象可被客戶激活。遠(yuǎn)程引用層處理語義,管理單一或多重對象的通信,決定調(diào)用是發(fā)往一個服務(wù)器還是多個。傳輸層管理實(shí)際的連接,并且追蹤可以接受方法調(diào)用的遠(yuǎn)程對象。服務(wù)器端的骨干網(wǎng)完成對服務(wù)器對象實(shí)際的方法調(diào)用,并獲取返回值。返回值向下經(jīng)遠(yuǎn)程引用層、服務(wù)器端的傳輸層傳遞回客戶端,再向上經(jīng)傳輸層和遠(yuǎn)程調(diào)用層返回。最后,樁程序獲得返回值。典型的服務(wù)器應(yīng)用程序?qū)?chuàng)建多個遠(yuǎn)程對象,并使這些遠(yuǎn)程對象能夠被引用,然后等待客戶機(jī)調(diào)用這些遠(yuǎn)程對象提供的方法。典型的客戶機(jī)程序則從服務(wù)器中得到一個或多個遠(yuǎn)程對象的引用,然后調(diào)用遠(yuǎn)程對象的方法。
9.3RMI實(shí)現(xiàn)技術(shù)
9.3.1RMI類和工具
利用RMI編寫分布式對象應(yīng)用程序需要五個類庫包和三個應(yīng)用軟件工具。其中,五個類庫包分別是:
java.rmi,提供客戶端的RMI類、接口和異常類;
java.rmi.server,提供服務(wù)器端的RMI類,接口和異常類;
java.rmi.registry,用于管理RMI命名服務(wù)的類;
java.rmi.dgc,用于管理分布式垃圾收集(Distributional
GarbageCollection)的類;
java.rmi.activation,用于按需激活的RMI服務(wù)的類。三個應(yīng)用軟件工具均包含在JSDK安裝路徑的bin目錄下,分別是:
rmic.exe,它是RMI編譯器,在使用javac編譯java源程序后,還需要使用rmic編譯服務(wù)器端的class文件,用于生成stub和skeleton;
rmiregistry.exe,一個為RMI提供命名服務(wù)的服務(wù)器,這項(xiàng)服務(wù)把名字和對象關(guān)聯(lián)在一起,即將RMI服務(wù)注冊為一個遠(yuǎn)程對象以便客戶端的調(diào)用;
rmi.exe,一個支持RMI激活框架的服務(wù)器。9.3.2RMI實(shí)現(xiàn)流程
因?yàn)镽MI允許調(diào)用程序?qū)⒓僇ava對象傳給遠(yuǎn)程對象,所以RMI將提供必要的機(jī)制,既可以加載對象的代碼又可以傳輸對象的數(shù)據(jù)。在RMI分布式應(yīng)用程序運(yùn)行時,服務(wù)器調(diào)用注冊服務(wù)程序以使名字與遠(yuǎn)程對象相關(guān)聯(lián)。客戶機(jī)在服務(wù)器上的注冊服務(wù)程序中用遠(yuǎn)程對象的名字查找該遠(yuǎn)程對象,然后調(diào)用它的方法。利用RMI編寫分布式對象應(yīng)用程序需要完成以下工作:
●?定位遠(yuǎn)程對象。應(yīng)用程序可使用兩種機(jī)制中的一種得到對遠(yuǎn)程對象的引用。它既可用RMI的簡單命名工具rmiregistry來注冊它的遠(yuǎn)程對象,也可以將遠(yuǎn)程對象引用作為常規(guī)操作的一部分來進(jìn)行傳遞和返回。●?與遠(yuǎn)程對象通信。遠(yuǎn)程對象間通信的細(xì)節(jié)由RMI處理,對于程序員來說,遠(yuǎn)程通信看起來就像標(biāo)準(zhǔn)的Java方法調(diào)用。
●?給作為參數(shù)或返回值傳遞的對象加載類字節(jié)碼。
為了實(shí)現(xiàn)以上工作,RMI實(shí)現(xiàn)的步驟如下:
(1)定義遠(yuǎn)程服務(wù)接口,該接口必須聲明為public,必須繼承java.rmi.Remote接口。在接口定義中說明服務(wù)器提供的方法特性,包含了方法的名字和參數(shù),這個服務(wù)方法必須拋出異常java.rmi.RemoteException;
(2)實(shí)現(xiàn)遠(yuǎn)程服務(wù)接口所定義的方法;
(3)利用rmic生成樁和框架文件;
(4)一個運(yùn)行遠(yuǎn)程服務(wù)的服務(wù)器;
(5)一個RMI命名服務(wù),它允許客戶端去發(fā)現(xiàn)這個遠(yuǎn)程服務(wù);
(6)注冊遠(yuǎn)程對象;
(7)類文件的提供者(一個HTTP或者FTP服務(wù)器);
(8)一個需要這個遠(yuǎn)程服務(wù)的客戶端程序。
【例9-1】定義遠(yuǎn)程服務(wù)接口,一個用于數(shù)組相加的遠(yuǎn)程服務(wù)接口。
1.importjava.rmi.*;
2.publicinterfaceArithextendsjava.rmi.Remote{
3.int[]add(inta[],intb[])throwsjava.rmi.RemoteException;
}
代碼注釋如下:
①第1行引用了重要的RMI類庫包;
②第2行定義了自定義的遠(yuǎn)程接口Arith,該接口必須具有公開(public)屬性,而且繼承了java.rmi.Remote接口;
③第3行申明一個沒有方法體的add(),并且該方法拋出了java.rmi.RemoteException異常。
代碼注釋如下:
①第1~2行引用重要類庫包和類;
②第3行定義遠(yuǎn)程服務(wù)類ArithImp1,它實(shí)現(xiàn)了事先定義遠(yuǎn)程服務(wù)接口Arith,并且繼承了UnicastRemoteObject類,用于遠(yuǎn)程單播傳輸對象;
③第4行定義成員屬性,用于存儲該遠(yuǎn)程服務(wù)的名稱;
④第5~8行定義構(gòu)造方法,通過super()指定本遠(yuǎn)程服務(wù)的名稱;
⑤第9~14行覆蓋了Arith接口的add()方法,實(shí)現(xiàn)了數(shù)組相加功能;⑥第16~17行定義RMI安全管理器實(shí)例,并加入到系統(tǒng)的安全管理器中;
⑦第18~24行創(chuàng)建遠(yuǎn)程對象的對象實(shí)例名稱為obj,通過rebind()注冊了遠(yuǎn)程服務(wù)名稱ArithServer,將該服務(wù)綁定在“//localhost:3000/ArithServer”,使本地環(huán)回測試用戶可用。
該程序僅說明遠(yuǎn)程服務(wù)的內(nèi)容,運(yùn)行該服務(wù)還需要特殊的指令。
客戶端是調(diào)用服務(wù)的,它提供用于服務(wù)的數(shù)據(jù)和獲得服務(wù)結(jié)果,如例9-3提供了兩個準(zhǔn)備相加的數(shù)組。
代碼注釋如下:
①第1~2行引用重要的類庫包;
②第5~7行給出了用于服務(wù)的兩個數(shù)組a[]?和b[]?以及用于存儲結(jié)果的數(shù)組result[];
③第9行查找在遠(yuǎn)程服務(wù)器localhost端口3000上開放的注冊服務(wù)ArithServer,并生成遠(yuǎn)程引用對象obj;
④第10行調(diào)用遠(yuǎn)程方法調(diào)用和傳遞參數(shù);
⑤第14~17行輸出結(jié)果。
在第4章中,曾經(jīng)提到使用多線程實(shí)現(xiàn)累加計(jì)數(shù)器,現(xiàn)在將它修改為采用RMI完成數(shù)值的累加。其不同之處在于,原程序在一臺計(jì)算機(jī)上啟動多個線程共同完成累加任務(wù),現(xiàn)在變更為由多臺計(jì)算機(jī)同時完成累加任務(wù)。為了使觀察效果更好,將累加范圍改為1~10?000,并設(shè)置了計(jì)時器,通過計(jì)算所消耗時間來判斷是否得到優(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)行在兩臺不同的服務(wù)器上,供客戶端調(diào)用。
代碼注釋如下:
①第1~2行引用重要類庫包和類;
②第3行定義遠(yuǎn)程服務(wù)類SumImp,它實(shí)現(xiàn)了事先定義遠(yuǎn)程服務(wù)接口Sum,并且繼承了UnicastRemoteObject類,用于遠(yuǎn)程單播傳輸對象;
③第4行定義成員屬性,用于存儲該遠(yuǎn)程服務(wù)的名稱;
④第5~8行定義構(gòu)造方法,通過super()?指定本遠(yuǎn)程服務(wù)的名稱;
⑤第9~14行覆蓋了Sum接口的add()?方法,實(shí)現(xiàn)了數(shù)組相加功能;⑥第16~17行定義RMI安全管理器實(shí)例,并加入到系統(tǒng)的安全管理器中;
⑦第18~24行創(chuàng)建遠(yuǎn)程對象的對象實(shí)例名稱為obj,通過rebind()注冊了遠(yuǎn)程服務(wù)名稱SumServer,將該服務(wù)綁定在“//服務(wù)運(yùn)行的地址:3000/SumServer”,該服務(wù)運(yùn)行的地址需要根據(jù)運(yùn)行環(huán)境獲得。
【例9-6】客戶端將一個1~10000的累加工作分配到兩個遠(yuǎn)程服務(wù)器上。
代碼注釋如下:
①第1~2行引用重要的類庫;
②第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行自定義兩個線程對象,帶入?yún)?shù),指定數(shù)值累加區(qū)間和遠(yuǎn)程服務(wù)名稱;
⑥第28~29,31行啟動線程;
⑦第28、31、33行用于記錄累加所用的時間;
⑧第30行將這兩個子線程添加到主線程中,保證子線程先于主線程結(jié)束。9.3.3RMI運(yùn)行步驟
由于RMI程序的運(yùn)行依賴于網(wǎng)絡(luò)的遠(yuǎn)程調(diào)用,它涉及安全問題,因而不同于普通的JavaApplication程序,其運(yùn)行一共分為五步:
(1)使用javac*.java分別編譯接口程序、服務(wù)端程序和客戶端程序。
(2)使用rmic服務(wù)端的?.class文件,產(chǎn)生一個服務(wù)端的_Stub.class的產(chǎn)生樁和框架文件。樁和框架在服務(wù)器端運(yùn)行時確定,根據(jù)需要動態(tài)裝載,采用rmic編譯器生成stub和skeleton。例如:rmicrmiExampl,在JDK1.5下,該命令執(zhí)行后將生成一個樁文件,文件名為rmiExampl_Stub.class。
(3)使用startrmiregistry,在服務(wù)端啟動一個RMI注冊表,便于對服務(wù)端提供的遠(yuǎn)程服務(wù)進(jìn)行注冊;RMI注冊表是一個名字服務(wù),允許客戶程序獲得對遠(yuǎn)程對象的引用,在服務(wù)器/客戶程序之前,必須啟動RMI注冊表。啟動方式:
startrmiregistry
默認(rèn)情況下,啟動的端口為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ù)localhost。
在運(yùn)行時,有可能出現(xiàn)如圖9-3所示的提示。圖9-3RMI服務(wù)端運(yùn)行提示該提示中提到程序運(yùn)行中出現(xiàn)了訪問控制異常(AccessControlException),對地址3000端口的連接和解析服務(wù)訪問被拒絕。出現(xiàn)該異常則說明程序運(yùn)行還缺少策略文件。9.3.4策略文件
RMI程序是一個調(diào)用分布式資源的網(wǎng)絡(luò)程序,運(yùn)行客戶端通過服務(wù)端的指定的端口訪問資源,需要控制的安全機(jī)制來保護(hù)服務(wù)端。在RMI中利用策略文件,對計(jì)算機(jī)端口的訪問進(jìn)行某些設(shè)置。
策略文件是一個文本文件,里面記錄了一些對計(jì)算機(jī)資源訪問的方式,比如對本地文件的訪問控制,對端口的訪問控制等。其文件后綴名為“*.policy”。在Windows系
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024版住宅電梯租賃及維修基金管理合同3篇
- 2024版房地產(chǎn)擔(dān)保合同屬性與風(fēng)險(xiǎn)防范3篇
- 2024年度勞動合同標(biāo)的及員工崗位描述2篇
- 2024版汽車展覽贊助合同3篇
- 2024年度博物館展覽品搬遷運(yùn)輸合同3篇
- 2024年地產(chǎn)收購合同模板3篇
- 2024版離婚協(xié)議起草與婚姻關(guān)系解除及財(cái)產(chǎn)分割專業(yè)合同2篇
- 2024年消防設(shè)施設(shè)備維保與應(yīng)急響應(yīng)合同3篇
- 2024年知識產(chǎn)權(quán)許可使用合同樣本及注意事項(xiàng)
- 2024年度車隊(duì)租賃與車輛保養(yǎng)合同范本3篇
- 五年級信息技術(shù)上冊期末測試卷答案
- 2019第五版新版PFMEA-注塑實(shí)例
- 新團(tuán)員入團(tuán)儀式PPT模板
- 八年級歷史上冊教案:第16課 毛澤東開辟井岡山道路
- 腸梗阻完整版課件
- 河南神火興隆礦業(yè)有限責(zé)任公司泉店煤礦礦產(chǎn)資源開采與生態(tài)修復(fù)方案
- 2023年考研考博-考博英語-西北農(nóng)林科技大學(xué)考試歷年真題摘選含答案解析
- 公路工程施工安全生產(chǎn)檢查要點(diǎn)
- 學(xué)校食堂設(shè)施設(shè)備維護(hù)保養(yǎng)制度
- GB/T 2820.5-2009往復(fù)式內(nèi)燃機(jī)驅(qū)動的交流發(fā)電機(jī)組第5部分:發(fā)電機(jī)組
- 電廠化學(xué)系統(tǒng)簡介課件
評論
0/150
提交評論