codefans

          導(dǎo)航

          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          統(tǒng)計(jì)

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          程序設(shè)計(jì)鏈接

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          RMI入門

          來源:http://ybwen.home.chinaren.com

          為通過網(wǎng)絡(luò)執(zhí)行其他機(jī)器上的代碼,傳統(tǒng)的方法不僅難以學(xué)習(xí),而且易出錯(cuò)。解決這個(gè)問題的最佳方法是:某些對(duì)象正好位于另一臺(tái)機(jī)器,我們可以發(fā)送一條消息,并獲得返回結(jié)果,就像位于自己的本機(jī)器一樣。Java遠(yuǎn)程方法調(diào)用(RMI)特性使客戶機(jī)上運(yùn)行的程序可以調(diào)用遠(yuǎn)程服務(wù)器上的對(duì)象。遠(yuǎn)程方法調(diào)用特性使Java編程人員能夠在網(wǎng)絡(luò)環(huán)境中分布操作。

          下面介紹一下必要的步驟,創(chuàng)建自己的RMI對(duì)象。

          一、遠(yuǎn)程接口概念:

               RMI對(duì)接口有著強(qiáng)烈的依賴。在需要?jiǎng)?chuàng)建一個(gè)遠(yuǎn)程對(duì)象的時(shí)候,我們通過傳遞一個(gè)接口來隱藏基層的實(shí)施細(xì)節(jié)。所以客戶得到遠(yuǎn)程對(duì)象的一個(gè)句柄正好同一些本地的根代碼連接,有后者負(fù)責(zé)通過網(wǎng)絡(luò)通信。但我們并不關(guān)心這些事情,通過自己的接口句柄發(fā)送消息即可。

             創(chuàng)建一個(gè)遠(yuǎn)程接口時(shí),必須遵守下列規(guī)則:

          1)  遠(yuǎn)程接口必須為public屬性(不能有“包訪問”;也就是說,他不能是“友好的”)。否則,一旦客戶試圖裝載一個(gè)實(shí)現(xiàn)了遠(yuǎn)程接口的遠(yuǎn)程對(duì)象,就會(huì)得到一個(gè)錯(cuò)誤。

          2)  遠(yuǎn)程接口必須擴(kuò)展接口java.rmi.Remote。

          3)  除與應(yīng)用程序本身有關(guān)的違例,遠(yuǎn)程接口中的每個(gè)方法都必須在自己的throws從句中聲明java.rmi.RemoteException.

          4)  作為參數(shù)或返回值傳遞的一個(gè)遠(yuǎn)程對(duì)象(不管是直接,還是本地對(duì)象中嵌入)必須聲明為遠(yuǎn)程接口,不可聲明為實(shí)施類。

          下面是一個(gè)遠(yuǎn)程接口示例,

          //PerfectTimeI.java
          //The PerfectTime remote interface
          package rmi.sample.server;
          import java.rmi.*;
          public interface PerfectTimeI extends Remote { 
              long getPerfectTime() throws RemoteException;
          }

          它表面上與其他的接口類似,只是對(duì)Remote進(jìn)行了擴(kuò)展,而且所有的方法都會(huì)“擲”出RemoteException.接口和方法都是Public的。

          編譯PerfectTimeI.java,生成PerfectTimeI.class(test是包,編譯時(shí)注意路徑)

          javac rmi.sample.server.PerfectTimeI.java

          二、遠(yuǎn)程接口的實(shí)施:

              服務(wù)器必須包含一個(gè)擴(kuò)展了UnicastRemoteObject類,并實(shí)現(xiàn)遠(yuǎn)程接口。這個(gè)類也可以含有附加的方法,但客戶只能使用遠(yuǎn)程接口中的方法。因?yàn)榭蛻羰侵赶蚪涌诘囊粋€(gè)句柄,而不是它的哪個(gè)類。

             必須為遠(yuǎn)程對(duì)象定義構(gòu)件器,即使只準(zhǔn)備定義一個(gè)默認(rèn)構(gòu)件器,用它調(diào)用基礎(chǔ)類構(gòu)件器。必須把它明確地編寫出來,因?yàn)樗仨殹皵S”出RemoteException違例。

            下面列出遠(yuǎn)程接口PerfectTime的事實(shí)過程:他代表精確計(jì)時(shí)服務(wù)

          //PerfectTime.java

          //The implementation of the PerfectTime remote object

          package rmi.sample.server;

          import java.net.*;
          import java.rmi.*;
          import java.rmi.registry.*;
          import java.rmi.server.*;
          public class PerfectTime extends UnicastRemoteObject implements PerfectTimeI {
          //默認(rèn)構(gòu)件器,也要“擲”出RemoteException違例。 
              public PerfectTime() throws RemoteException { 
                  super(); 
              }

          public long getPerfectTime() throws RemoteException { 
              return System.currentTimeMillis();
          }

          public static void main(String[] args) {
          /*創(chuàng)建和安裝一個(gè)安全管理器,令其支持RMI.作為Java開發(fā)包的一部分,適用于RMI唯一一個(gè)是RMISecurityManager.*/ 
          //    System.setSecurityManager(new RMISecurityManager());

              try { 
             /*創(chuàng)建遠(yuǎn)程對(duì)象的一個(gè)或多個(gè)實(shí)例,下面是PerfectTime對(duì)象*/ 
                  PerfectTime pt = new PerfectTime(); 
             /*向RMI遠(yuǎn)程對(duì)象注冊(cè)表注冊(cè)至少一個(gè)遠(yuǎn)程對(duì)象。一個(gè)遠(yuǎn)程對(duì)象擁有的方法即可生成指向其他遠(yuǎn)程對(duì)象的句柄,這樣,客戶到注冊(cè)表里訪問一次,得到第一個(gè)遠(yuǎn)程對(duì)象即可.*/ 
                  Naming.bind("PerfectTime", pt); 
                  System.out.println("Ready to do Time"); 
              } catch (Exception e) { 
                  e.printStackTrace(); 
              }
          }
          }

          編譯PerfectTime.java,生成PerfectTime.class(rmi.sample.server是包,編譯時(shí)注意路徑)
          javac rmi.sample.server.PerfectTime.java

          三、創(chuàng)建根和干:

            創(chuàng)建RemoteObject的主干和框架。要完成這個(gè)工作可使用rmic編譯器,rmic編譯器生成遠(yuǎn)程對(duì)象的存根和骨架。存根(Stub)是遠(yuǎn)程對(duì)象在客戶端的代理,它將RMI調(diào)用傳遞給服務(wù)器端的骨架(Skeleton),后者負(fù)責(zé)將該調(diào)用傳遞給實(shí)際的遠(yuǎn)程方法輸入如下:

          rmic rmi.sample.server.PerfectTime

           執(zhí)行這個(gè)命令,

          rmic成功運(yùn)行,rmi.sample.server目錄里就會(huì)多出兩個(gè)新類:

          PerfectTime_Stub.class
          PerfectTime_Skel.class

          它們分別對(duì)應(yīng)的是根(stub)和骨架(skeleton).

          四、使用遠(yuǎn)程對(duì)象:

          RMI全部的宗旨就是可能簡(jiǎn)化遠(yuǎn)程接口對(duì)象的使用。我們客戶程序中要做的唯一一件額外事情是查找從服務(wù)器取回遠(yuǎn)程接口。下面就是編寫的Java程序:將消息發(fā)給對(duì)象:

          //DisplayPerfectTime.java
          //Users remote object PerfectTime

          package rmi.sample.client;
          import java.rmi.*;
          import java.rmi.registry.*;
          public class DisplayPerfectTime {
          /*** DisplayPerfectTime 構(gòu)造子注解。*/
          public DisplayPerfectTime() { 
              super();
          }

          public static void main(String[] args) { 
             // System.setSecurityManager(new RMISecurityManager()); 
              try { 
                  PerfectTimeI t = (PerfectTimeI) Naming.lookup("PerfectTime"); 
                 for (int i = 0; i < 10; i++) { 
                     System.out.println("PerfectTime:" + t.getPerfectTime()); 
                
              } catch (Exception e) { 
                  e.printStackTrace(); 
              }
          }
          }

          編譯DisplayPerfectTime.java.
          javac rmi.sample.client.DisplayPerfectTime.java

          五、啟動(dòng)注冊(cè)并運(yùn)行代碼:

          在運(yùn)行PerfectTime類和DisplayPectTime類之前,用戶必須首先在將要宿主PerfectTime的計(jì)算機(jī)上啟動(dòng)RMI注冊(cè)(Registry)程序,即使將要運(yùn)行PerfectTime的計(jì)算機(jī)與運(yùn)行DisplayPerfectTime的是同一臺(tái)機(jī)器,這一步也是必須的。注冊(cè)表服務(wù)器的名字是rmiregistry.在32位Windows環(huán)境中,可使用: start rmiregistry 令其在后臺(tái)運(yùn)行。然后分別開兩個(gè)不同的進(jìn)程運(yùn)行Server端和Client端:?jiǎn)?dòng)注冊(cè)表服務(wù)器:

          start rmiregistry

          綁定PerfectTime到注冊(cè),運(yùn)行服務(wù)端程序:在Windows下,輸入下列命令,在后臺(tái)啟動(dòng)PerfectTime程序:

          java rmi.sample.server.PerfectTime

          Ready to do Time

          運(yùn)行客戶端程序:如下

          G:\RMI>java rmi.sample.client.DisplayPerfectTime

          PerfectTime:961722589649
          PerfectTime:961722589669
          PerfectTime:961722589679
          PerfectTime:961722589679
          PerfectTime:961722589689
          PerfectTime:961722589689
          PerfectTime:961722589689
          PerfectTime:961722589699
          PerfectTime:961722589699
          PerfectTime:961722589699

          RMI程序要注意以下幾點(diǎn):
          1,rmiregistry必須要能夠找到stub,skeleton
          2,若RMI涉及到Socket讀寫,必須自己寫一個(gè)Java策略文件。

          posted on 2006-02-25 11:11 春雷的博客 閱讀(188) 評(píng)論(0)  編輯  收藏 所屬分類: java technology


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 温州市| 井冈山市| 沙坪坝区| 澄迈县| 永寿县| 象山县| 滦南县| 天长市| 凤翔县| 丽江市| 延庆县| 广灵县| 民县| 汉中市| 达日县| 石景山区| 曲阳县| 伊宁市| 康马县| 临沧市| 大田县| 明溪县| 中阳县| 洪江市| 资阳市| 蕉岭县| 浙江省| 合作市| 邹平县| 娄烦县| 贵溪市| 务川| 南汇区| 子长县| 顺义区| 承德市| 明溪县| 治县。| 文山县| 贵州省| 遵义县|