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

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

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

    隨筆-11  評(píng)論-10  文章-8  trackbacks-0
    rmi有兩個(gè)主要問題:
    1. 調(diào)用如何從客戶端傳輸?shù)椒?wù)器端
       這個(gè)問題的是通過stub來解決的,stub負(fù)責(zé)和服務(wù)器通信,將調(diào)用傳輸?shù)椒?wù)器并接收
       返回值
    2. 由于stub類可以通過工具生成,但初始化必須在服務(wù)器端完成,所有如何將一個(gè)可用的
       stub傳輸?shù)娇蛻舳司褪俏覀冏铌P(guān)心的問題

    注:在1.4中stub類是必須的,在5.0中使用UnicastRemoteObject類可以不需要stub類
    而由動(dòng)態(tài)生成的Proxy類(實(shí)現(xiàn)遠(yuǎn)程接口,InvocationHandler是
    RemoteObjectInvocationHandler)代替,具體見5.0的文檔。如果不使用
    UnicastRemoteObject類,則stub類在服務(wù)器端是必須的

    rmi的核心問題是如何將一個(gè)可用的stub傳輸?shù)娇蛻舳?/span>,大致有兩種方法:
    1. 最直觀的方法,服務(wù)器和客戶端直接建立連接,用任何可用的協(xié)議傳輸stub,缺點(diǎn)顯而
       易見,客戶端必須明確的知道服務(wù)器的地址及相關(guān)信息
    2. 使用注冊(cè)中心,如:rmiregistry和JNDI。這里主要討論使用rmiregistry的情況

    有一點(diǎn)需要注意,這里傳輸?shù)闹皇莝tub的實(shí)例,而不是stub類的定義。所有stub類文件必須
    在客戶端和服務(wù)器端的classpath中,否則會(huì)拋出ClassNotFoundException。這樣要求客戶
    端確實(shí)有些過分,我們希望客戶端只要遠(yuǎn)程接口的定義就夠了,這實(shí)際上很容易辦到,下面
    我們就來討論這個(gè)問題

    Dynamic code downloading using RMI
    (http://java.sun.com/j2se/1.4.2/docs/guide/rmi/codebase.html)

    要下載類必須設(shè)置RMISecurityManager,默認(rèn)是禁止下載的

    客戶端可以通過網(wǎng)絡(luò)自動(dòng)下載stub,此時(shí)stub不需要在客戶端的classpath中,只需要遠(yuǎn)程
    接口即可。

    由rmiregistry作為注冊(cè)中心的遠(yuǎn)程調(diào)用

    在服務(wù)器綁定遠(yuǎn)程對(duì)象到rmiregistry時(shí),rmiregistry必須能夠找到該對(duì)象的stub,它在三
    個(gè)地方尋找:
    1. 啟動(dòng)它時(shí)的CLASSPATH環(huán)境變量

    2. 啟動(dòng)它時(shí)所在的文件夾作為classpath尋找

    3. 該stub中的codebase,這個(gè)值由服務(wù)器通過系統(tǒng)屬性 java.rmi.server.codebase 設(shè)置

    若找不到則無法綁定

    客戶端通過rmiregistry lookup到stub對(duì)象,虛擬機(jī)從兩個(gè)位置尋找stub類的定義:
    1. classpath中尋找

    2. stub中的codebase,這個(gè)值由rmi服務(wù)器通過系統(tǒng)屬性 java.rmi.server.codebase 設(shè)置

    由以上分析可見,服務(wù)器端只要正確設(shè)置了codebase,無論何種情況,遠(yuǎn)程調(diào)用都能順利完成

    不僅客戶端可以從服務(wù)器下載類,服務(wù)器也可以從客戶端下載類,只需要在客戶端設(shè)置
    codebase,安裝RMISecurityManager即可

    若服務(wù)器允許下載類,則客戶端有可能在服務(wù)器上運(yùn)行任何他希望的代碼,如以下代碼:
    // 遠(yuǎn)程接口定義
    package
    rmi.server;

    import java.rmi.Remote;
    import java.rmi.RemoteException;

    public interface Service extends Remote {
    public void hello() throws RemoteException;

    public void runThread(Runnable thread) throws RemoteException;
    }

    // 遠(yuǎn)程接口實(shí)現(xiàn),main方法作為服務(wù)器
    package
    rmi.server;

    import java.rmi.Naming;
    import java.rmi.RMISecurityManager;
    import java.rmi.RemoteException;
    import java.rmi.server.RemoteStub;
    import java.rmi.server.UnicastRemoteObject;
    import java.security.Permission;

    public class ServiceImpl implements Service {

    private RemoteStub stub;

    private int count;

    public ServiceImpl() throws RemoteException {
    stub
    = UnicastRemoteObject.exportObject(this);
    count
    = 0;
    }

    public void hello() throws RemoteException {
    System.out.println(
    "Hello World: count = " + (++count));
    }

    public void runThread(Runnable thread) throws RemoteException {
    Thread t
    = new Thread(thread);
    t.start();
    }

    public RemoteStub getStub() {
    return stub;
    }

    public static void main(String[] args) {
    System.setProperty(
    "java.rmi.server.ignoreStubClasses", "true");
    System.setProperty(
    "java.rmi.server.codebase",
    "file:///E:\\\\bahamut\\\\JavaWorkspace\\\\rmiserver\\\\classes\\\\");
    if (System.getSecurityManager() == null) {
    System.setSecurityManager(
    new RMISecurityManager() {
    public void checkPermission(Permission p) {
    }
    });
    }
    try {
    ServiceImpl service
    = new ServiceImpl();
    Naming.rebind(
    "service", service);
    System.out.println(
    "Server ready");
    }
    catch (Exception e) {
    e.printStackTrace();
    }
    }

    }

    // 客戶端
    package
    rmi.client;

    import java.rmi.Naming;
    import java.rmi.RMISecurityManager;
    import java.security.Permission;

    import rmi.server.Service;

    public class ServiceClient {

    /**
    *
    @param args
    */
    public static void main(String[] args) {
    System.setProperty(
    "java.rmi.server.codebase",
    "file:///E:\\\\bahamut\\\\JavaWorkspace\\\\rmiclient\\\\classes\\\\");
    if (System.getSecurityManager() == null) {
    System.setSecurityManager(
    new RMISecurityManager() {
    public void checkPermission(Permission p) {
    }
    });
    }
    try {
    Service service
    = (Service) Naming.lookup("service");
    service.hello();
    Runnable runner
    = new Runner();
    service.runThread(runner);
    }
    catch (Exception e) {
    e.printStackTrace();
    }
    }

    }
    package rmi.client;

    import java.io.Serializable;

    public class Runner implements Runnable, Serializable {

    public void run() {
    System.out.println(
    "i'm runner");
    }

    }

    服務(wù)器端生成stub并放在classpath中,codebase設(shè)置為能找到stub的路徑,運(yùn)行rmiregistry,
    運(yùn)行服務(wù)器。

    客戶端只需要Service類在classpath中,設(shè)置codebase為能找到Runner的路徑,運(yùn)行客戶端。
    客戶端會(huì)從服務(wù)器下載stub,服務(wù)器會(huì)從客戶端下載Runner。Runner可以執(zhí)行任何操作甚至破壞
    服務(wù)器上的數(shù)據(jù)。

    多次運(yùn)行客戶端可以發(fā)現(xiàn)count在增長,也就是說對(duì)于export出的遠(yuǎn)程對(duì)象,狀態(tài)是始終保存的
    posted on 2005-11-11 19:49 JBahamut 閱讀(1540) 評(píng)論(1)  編輯  收藏

    評(píng)論:
    # re: 關(guān)于rmi的研究 2009-03-31 16:14 | 夏登成
    謝謝你,讓我明白了遠(yuǎn)程方法調(diào)用!  回復(fù)  更多評(píng)論
      

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 国产精品成人免费一区二区 | 亚洲精品无码久久久久YW| 日本一道高清不卡免费| 成在人线av无码免费高潮水| 亚洲激情在线视频| 国产小视频在线观看免费| 十八禁视频在线观看免费无码无遮挡骂过| 亚洲成在人线电影天堂色| 亚洲AV之男人的天堂| 2021精品国产品免费观看| 午夜成人无码福利免费视频| 亚洲另类小说图片| 国产亚洲一区二区三区在线不卡| a拍拍男女免费看全片| 一级黄色片免费观看| 亚洲国产成人99精品激情在线 | 久久精品国产亚洲AV未满十八| 亚洲狠狠婷婷综合久久久久| 日韩激情无码免费毛片| 久久久久久国产精品免费免费男同 | 亚洲AV无码成人精品区在线观看 | 无遮免费网站在线入口| 中文字幕av免费专区| 亚洲AV永久无码精品网站在线观看| 久久久亚洲精品国产| 亚洲精品国产精品乱码不卞| 天天拍拍天天爽免费视频| 1区2区3区产品乱码免费| 中文字字幕在线高清免费电影| 久久亚洲精品11p| 久久精品国产亚洲av麻豆图片| 国产亚洲精品美女久久久 | 亚洲春黄在线观看| 亚洲人成网站在线观看播放| 亚洲AV无码一区二区三区在线观看 | 成人在线免费观看| 亚洲高清视频免费| 久久青草精品38国产免费| 99re6在线精品免费观看| 一二三四在线观看免费中文在线观看 | 亚洲日韩人妻第一页|