<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    細(xì)心!用心!耐心!

    吾非文人,乃市井一俗人也,讀百卷書(shū),跨江河千里,故申城一游; 一兩滴辛酸,三四年學(xué)業(yè),五六點(diǎn)粗墨,七八筆買(mǎi)賣(mài),九十道人情。

    BlogJava 聯(lián)系 聚合 管理
      1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks

    用RMI進(jìn)行遠(yuǎn)程方法調(diào)用

     
    遠(yuǎn)程方法調(diào)用(RMI)機(jī)制可以把面向?qū)ο蟮乃枷脒M(jìn)一步擴(kuò)展,因?yàn)槟憧梢哉{(diào)用的對(duì)象不僅可以在本機(jī)上,也可以在別的主機(jī)上。本文就簡(jiǎn)單介紹rmi的編程方法。
      首先介紹一些簡(jiǎn)單的rmi的概念。
      1, 服務(wù)器和客戶(hù):在rmi中,如果有一個(gè)對(duì)象進(jìn)行遠(yuǎn)程方法調(diào)用,這個(gè)對(duì)象就叫做客戶(hù)機(jī)對(duì)象,而遠(yuǎn)程對(duì)象則被稱(chēng)為服務(wù)器對(duì)象。
      2, 創(chuàng)建服務(wù)器對(duì)象的服務(wù)器程序:這個(gè)程序用來(lái)創(chuàng)建服務(wù)器對(duì)象,注冊(cè)這個(gè)對(duì)象,使得客戶(hù)可以通過(guò)注冊(cè)的名稱(chēng)訪(fǎng)問(wèn)服務(wù)器對(duì)象。
      3, 接口(interface),接口可以讓客戶(hù)端了解服務(wù)器所能做的工作。更具體的說(shuō),就是它列出了可以在服務(wù)器上執(zhí)行的所有方法。客戶(hù)端程序必須能夠找到這個(gè)類(lèi),否則就不能執(zhí)行對(duì)服務(wù)器函數(shù)的調(diào)用。
      4, 客戶(hù)樁(stub),有的書(shū)中翻譯成為代碼存根,它給客戶(hù)端程序提供一個(gè)樁,這個(gè)樁上"綁"著服務(wù)器對(duì)象。當(dāng)客戶(hù)程序需要調(diào)用遠(yuǎn)程對(duì)象時(shí),這個(gè)樁被下載到客戶(hù)端(如果客戶(hù)端有這個(gè)類(lèi),則不需要下載)。然后客戶(hù)就可以像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程的方法了。
      這個(gè)客戶(hù)樁的作用是將客戶(hù)向服務(wù)器的請(qǐng)求進(jìn)行編碼、進(jìn)行傳輸,服務(wù)器執(zhí)行這次調(diào)用后將結(jié)果返回到客戶(hù)樁,客戶(hù)樁進(jìn)行解碼,將解碼后的結(jié)果傳送到客戶(hù)程序中。對(duì)于編寫(xiě)客戶(hù)端的程序員來(lái)說(shuō),他不需要知道其中的具體過(guò)程。
      客戶(hù)樁不需要自己編寫(xiě),后面會(huì)說(shuō)明它的生成方法。它實(shí)現(xiàn)了前述的接口(interface)。
      下面就通過(guò)一個(gè)例子來(lái)說(shuō)明編寫(xiě)的過(guò)程。
      1, 編寫(xiě)服務(wù)器的接口:這一步是最主要的部分,因?yàn)榻涌谑沁B接客戶(hù)機(jī)與服務(wù)器的關(guān)鍵部分。在這個(gè)例子中,接口很簡(jiǎn)單,代碼如下:
      import java.rmi.*;
      public interface Product extends Remote
      {
       String getDescription() throws RemoteException;
      }
      在這里應(yīng)注意的是,遠(yuǎn)程對(duì)象的接口一定要擴(kuò)展(extend)Java.rmi包的Remote接口。同時(shí)接口中的所有的方法都要聲明拋出RemoteException異常。這是因?yàn)橛捎诰W(wǎng)絡(luò)連接的不可靠性,遠(yuǎn)程方法調(diào)用很可能失敗。如果不聲明異常,在遠(yuǎn)程方法調(diào)用失敗后,應(yīng)用程序就會(huì)無(wú)法結(jié)束。
      2, 編寫(xiě)服務(wù)器對(duì)象:
      Java中具有一個(gè)可以直接使用的服務(wù)器類(lèi)--UniCastRemoteObject。它存在于Java.rmi.server包中。我們可以直接擴(kuò)展這個(gè)類(lèi),使它實(shí)現(xiàn)前述的接口。這樣就可以使服務(wù)器滿(mǎn)足我們的需要。
      import java.rmi.server.*;
      import java.rmi.*;
      public class ProductImpl extends UnicastRemoteObject implements Product
      {
       public ProductImpl(String name) throws RemoteException
       {
        Desc = name;
       }
       public String getDescription() throws RemoteException
       {
        return "This is "+Desc+" product";
       }
       private String Desc;
      }
      可以看到,rmi服務(wù)器的實(shí)現(xiàn)和其他的方法代碼沒(méi)有什么不同。
      3, 編寫(xiě)創(chuàng)建服務(wù)器對(duì)象的服務(wù)器程序:
      import java.rmi.*;
      public class ProductServer
      {
       public static void main(String[] args)
       {
        try
        {
         System.out.println("Constructin Server implementations ....");
         ProductImpl p1 = new ProductImpl("toaster");
         ProductImpl p2 = new ProductImpl("microwave");
         System.out.println("Binding server implementations to registry");
         Naming.rebind("toaster",p1);
         Naming.rebind("microwave",p2);
         System.out.println("waiting for clients...");
        }catch(Exception e)
        {
         System.out.println("Error "+e);
        }
       }
      }
      通過(guò)代碼可以看到,這個(gè)服務(wù)器首先創(chuàng)建了兩個(gè)服務(wù)器對(duì)象。然后使用Naming.rebind()方法,將這個(gè)對(duì)象和一個(gè)名稱(chēng)聯(lián)系(綁定)在一起。這個(gè)名稱(chēng)就是客戶(hù)機(jī)查找服務(wù)器對(duì)象所使用的名稱(chēng)。Naming是java.rmi包中的類(lèi)。這個(gè)類(lèi)的作用是建立一套查找對(duì)象的命名機(jī)制。通過(guò)它就可以將綁定在特定名稱(chēng)上的對(duì)象找到。
      4, 編寫(xiě)客戶(hù)端代碼:
      import java.rmi.*;
      import java.rmi.server.*;
      public class ProductClient
      {
       public static void main(String[] args)
       {
        System.out.println("begin to invoke remote method");
        System.setSecurityManager(new RMISecurityManager());
        String url = "rmi://91.1.1.119:1099/";
        try
        {
         file://查找遠(yuǎn)程對(duì)象
         System.out.println("1");
         Product c1 = (Product)Naming.lookup(url + "toaster");
         Product c2 = (Product)Naming.lookup(url + "microwave");
         file://調(diào)用遠(yuǎn)程方法
         System.out.println("2");
         System.out.println(c1.getDescription());
         System.out.println("3");
         System.out.println(c2.getDescription());
        }catch (Exception ex)
        {
         System.out.println("error "+ex);
        }
       }
      }
      在這段代碼中,首先定義了一個(gè)字符串url。這個(gè)字符串中存儲(chǔ)了找到遠(yuǎn)程服務(wù)器對(duì)象的協(xié)議和地址信息。在rmi中,所使用的協(xié)議是rmi,端口號(hào)是1099。這個(gè)例子中,我的服務(wù)器對(duì)象存放在ip地址為91.1.1.119的主機(jī)上,所以,這個(gè)字符串的值為rmi://91.1.1.119:1099/。
      接著,使用Naming.lookup()方法查找遠(yuǎn)程對(duì)象。參數(shù)就是服務(wù)器的位置信息和服務(wù)器對(duì)象所綁定的名稱(chēng)。
      這里需要注意的是,通過(guò)lookup方法得到其實(shí)不是服務(wù)器對(duì)象本身的引用,而是下載到客戶(hù)機(jī)上的客戶(hù)樁。但是,這個(gè)方法得到的是Object類(lèi)型,要使用這個(gè)對(duì)象,必須將它類(lèi)型轉(zhuǎn)換成服務(wù)器所實(shí)現(xiàn)的接口類(lèi)型。
      隨后,就可以像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程方法。在這個(gè)例子中,遠(yuǎn)程方法是getDescription()。
      因?yàn)檫@段代碼是對(duì)遠(yuǎn)程對(duì)象進(jìn)行操作,所以,它被放到一個(gè)try…catch塊中,來(lái)捕獲遠(yuǎn)程調(diào)用過(guò)程中的異常。
      最后,就要將服務(wù)器和客戶(hù)機(jī)部署到機(jī)器上。
      1,將所有的類(lèi)文件編譯為class文件。然后在dos方式下使用
      rmic ProductImpl
      就可以生成客戶(hù)樁,名為ProductImpl_Stub.class。
      2,把客戶(hù)端代碼和接口代碼拷貝到客戶(hù)機(jī)器上。
      3,運(yùn)行rmiregistry程序,啟動(dòng)注冊(cè)系統(tǒng),使得服務(wù)器可以注冊(cè)在機(jī)器上,以供客戶(hù)調(diào)用。
      4,啟動(dòng)http服務(wù)。將接口類(lèi)和客戶(hù)樁類(lèi)放在http服務(wù)器上,使得客戶(hù)可以下載。假設(shè)這兩個(gè)文件的下載目錄是http://91.1.1.119/download/
      5,使用start java -Djava.rmi.server.codebase= http://91.1.1.119/download/ ProductServer
      運(yùn)行創(chuàng)建服務(wù)器對(duì)象的程序。
      其中的-Djava.rmi.server.codebase= http://91.1.1.119/download/ 指明客戶(hù)程序下載客戶(hù)樁的地址。
      6,因?yàn)閞mi有安全限制,所以在客戶(hù)端必須建立一個(gè)策略文件。假設(shè)名為client.policy
      文件的內(nèi)容為
      grant
      {
       permission java.net.SocketPermission "91.1.1.119:1024-65535","connect";
       permission java.net.SocketPermission "91.1.1.119:80","connect";
      };
      使用 start java -Djava.security.policy=client.policy ProductClient 啟動(dòng)客戶(hù)端,客戶(hù)端就可以連接80端口(http端口)和1024-65535的端口(其中包含了rmi的缺省端口1099)。之后就可以看到程序的執(zhí)行結(jié)果。
      以上就是使用rmi進(jìn)行遠(yuǎn)程方法調(diào)用的基本過(guò)程。
      但是,應(yīng)該注意到,rmi有一個(gè)很大的限制,那就是只能在java編寫(xiě)的對(duì)象之間使用,如果要在不同的語(yǔ)言寫(xiě)成的對(duì)象之間通訊,那就需要CORBA的幫助
    posted on 2007-05-06 12:36 張金鵬 閱讀(109) 評(píng)論(0)  編輯  收藏

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 成人免费区一区二区三区| 亚洲人和日本人jizz| 在线免费视频一区二区| 99re免费在线视频| 成在线人免费无码高潮喷水| 亚洲成a人片在线观看精品| 麻豆亚洲av熟女国产一区二| 亚洲香蕉成人AV网站在线观看| 日本一道一区二区免费看| 8888四色奇米在线观看免费看| 可以免费观看的毛片| 国产无限免费观看黄网站| 青娱乐在线免费观看视频| 看亚洲a级一级毛片| 久久精品亚洲日本波多野结衣| 亚洲精品久久无码av片俺去也| 亚洲成aⅴ人片在线观| 亚洲人色大成年网站在线观看| 亚洲中文字幕久久精品无码2021| 亚洲第一页在线观看| 亚洲熟妇少妇任你躁在线观看| 黄色免费网址大全| 一级做a爱过程免费视频高清| 国产免费一区二区视频| 最新仑乱免费视频| 亚洲中文字幕无码专区 | 中日韩亚洲人成无码网站| 欧洲亚洲国产精华液| 韩国免费A级毛片久久| 日日麻批免费40分钟日本的| 深夜国产福利99亚洲视频| 久久精品亚洲综合专区| 久久精品亚洲AV久久久无码| 亚洲av色香蕉一区二区三区 | 亚洲中文久久精品无码ww16| 久久久久亚洲精品无码系列| 亚洲精品无码成人片久久不卡| 国产免费牲交视频免费播放| 最近最新MV在线观看免费高清| 亚洲VA中文字幕无码毛片| 色婷婷六月亚洲综合香蕉|