posts - 495,comments - 227,trackbacks - 0
          一 .RMI概述
          RMI(Remote Method Invocation)
              RMI是分布式對(duì)象軟件包,它簡(jiǎn)化了在多臺(tái)計(jì)算機(jī)上的JAVA應(yīng)用之間的通信。必須在jdk1.1以上

          RMI用到的類
               java.rmi.Remote                   所有可以被遠(yuǎn)程調(diào)用的對(duì)象都必須實(shí)現(xiàn)該接口
               java.rmi.server.UnicastRemoteObject  所有可以被遠(yuǎn)程調(diào)用的對(duì)象都必須擴(kuò)展該類
           
          什么是RMI
              遠(yuǎn)程方法調(diào)用是一種計(jì)算機(jī)之間對(duì)象互相調(diào)用對(duì)方函數(shù),啟動(dòng)對(duì)方進(jìn)程的一種機(jī)制,
          使用這種機(jī)制,某一臺(tái)計(jì)算機(jī)上的對(duì)象在調(diào)用另外一臺(tái)計(jì)算機(jī)上的方法時(shí),使用的程
          序語法規(guī)則和在本地機(jī)上對(duì)象間的方法調(diào)用的語法規(guī)則一樣。

          優(yōu)點(diǎn)
          這種機(jī)制給分布計(jì)算的系統(tǒng)設(shè)計(jì)、編程都帶來了極大的方便。
          只要按照RMI規(guī)則設(shè)計(jì)程序,可以不必再過問在RMI之下的網(wǎng)絡(luò)細(xì)節(jié)了,如:TCP和Socket等等。
          任意兩臺(tái)計(jì)算機(jī)之間的通訊完全由RMI負(fù)責(zé)。調(diào)用遠(yuǎn)程計(jì)算機(jī)上的對(duì)象就像本地對(duì)象一樣方便。
           
          1、面向?qū)ο螅?br /> RMI可將完整的對(duì)象作為參數(shù)和返回值進(jìn)行傳遞,而不僅僅是預(yù)定義的數(shù)據(jù)類型。
          也就是說,可以將類似Java哈西表這樣的復(fù)雜類型作為一個(gè)參數(shù)進(jìn)行傳遞。
           
          2、可移動(dòng)屬性:
          RMI可將屬性從客戶機(jī)移動(dòng)到服務(wù)器,或者從服務(wù)器移動(dòng)到客戶機(jī)。
           
          3、設(shè)計(jì)方式:
          對(duì)象傳遞功能使您可以在分布式計(jì)算中充分利用面向?qū)ο蠹夹g(shù)的強(qiáng)大功能,如二層和三層結(jié)構(gòu)系統(tǒng)。
          如果用戶能夠傳遞屬性,那么就可以在自己的解決方案中使用面向?qū)ο蟮脑O(shè)計(jì)方式。
          所有面向?qū)ο蟮脑O(shè)計(jì)方式無不依靠不同的屬性來發(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)免遭惡意小程序侵害而設(shè)計(jì)的安全管理程序。
          5、便于編寫和使用
          RMI使得Java遠(yuǎn)程服務(wù)程序和訪問這些服務(wù)程序的Java客戶程序的編寫工作變得輕松、簡(jiǎn)單。
          遠(yuǎn)程接口實(shí)際上就是Java接口。
          為了實(shí)現(xiàn)RMI的功能必須創(chuàng)建遠(yuǎn)程對(duì)象任何可以被遠(yuǎn)程調(diào)用的對(duì)象必須實(shí)現(xiàn)遠(yuǎn)程接口。但遠(yuǎn)程
          接口本身并不包含任何方法。因而需要?jiǎng)?chuàng)建一個(gè)新的接口來擴(kuò)展遠(yuǎn)程接口。
          新接口將包含所有可以遠(yuǎn)程調(diào)用的方法。遠(yuǎn)程對(duì)象必須實(shí)現(xiàn)這個(gè)新接口,由于新的接口擴(kuò)展了
          遠(yuǎn)程接口,實(shí)現(xiàn)了新接口,就滿足了遠(yuǎn)程對(duì)象對(duì)實(shí)現(xiàn)遠(yuǎn)程接口的要求,所實(shí)現(xiàn)的每個(gè)對(duì)象都將
          作為遠(yuǎn)程對(duì)象引用。
           
          個(gè)人總結(jié):
              RMI說白了,就是提供了一種遠(yuǎn)程的方法調(diào)用。 這種調(diào)用簡(jiǎn)單方便,可以傳遞復(fù)雜java對(duì)象。現(xiàn)在流行的j2ee中的EJB的底層實(shí)現(xiàn)技術(shù)就是RMI,EJB的調(diào)用就是經(jīng)過封裝的,更高級(jí)的RMI調(diào)用。


          下面我們就來寫一個(gè)RMI的程序:
           
          一.創(chuàng)建RMI程序的6個(gè)步驟:
          1、定義一個(gè)遠(yuǎn)程接口的接口,該接口中的每一個(gè)方法必須聲明它將產(chǎn)生一個(gè)RemoteException異常。
          2、定義一個(gè)實(shí)現(xiàn)該接口的類。
          3、使用RMIC程序生成遠(yuǎn)程實(shí)現(xiàn)所需的殘根和框架。
          4、創(chuàng)建一個(gè)服務(wù)器,用于發(fā)布2中寫好的類。
          5. 創(chuàng)建一個(gè)客戶程序進(jìn)行RMI調(diào)用。
          6、啟動(dòng)rmiRegistry并運(yùn)行自己的遠(yuǎn)程服務(wù)器和客戶程序。
           
          二. 程序詳細(xì)說明
           
          1.定義一個(gè)遠(yuǎn)程接口的接口,該接口中的每一個(gè)方法必須聲明它將產(chǎn)生一個(gè)RemoteException異常。
           
          import java.rmi.Remote;
          import java.rmi.RemoteException;
          public interface I_Hello extends java.rmi.Remote   //需要從Remote繼承
          {
                 public String SayHello() throws RemoteException;   //需要拋出remote異常
          }

             上面例子我們定義一個(gè)返回字符串的遠(yuǎn)程方法 SayHello(),這個(gè)遠(yuǎn)程接口 I_Hello必須是public的 ,它必須從java.rmi.Remote繼承而來,接口中的每一個(gè)方法都必須拋出遠(yuǎn)程異常java.rmi.RemoteException。

          拋出這個(gè)異常的原因
          由于任何遠(yuǎn)程方法調(diào)用實(shí)際上要進(jìn)行許多低級(jí)網(wǎng)絡(luò)操作,因此網(wǎng)絡(luò)錯(cuò)誤可能在調(diào)用過程中隨時(shí)發(fā)生。
          因此,所有的RMI操作都應(yīng)放到try-catch塊中。
            
          2、定義一個(gè)實(shí)現(xiàn)該接口的類。
           
           import java.io.PrintStream;
          import java.rmi.*;
          import java.rmi.server.UnicastRemoteObject;
           
          public class Hello extends UnicastRemoteObject   //必須從UnicastRemoteObject  繼承
                             implements I_Hello
          {
                  public Hello() throws RemoteException     //需要一個(gè)拋出Remote異常的默認(rèn)初始化方法
                  {
                  }
           
                  public String SayHello()     //這個(gè)是實(shí)現(xiàn)I_Hello接口的方法
                  {
                     return "Hello world !!";
                  }
          }
           
          實(shí)現(xiàn)接口的類必須繼承UnicastRemoteObject類。
          擴(kuò)展java.rmi.server.UnicastRemoteObject
          UnicastRemoteObject顧名思義,是讓客戶機(jī)與服務(wù)器對(duì)象實(shí)例建立一對(duì)一的連接。
           
          3、使用RMIC程序生成遠(yuǎn)程實(shí)現(xiàn)所需的殘根Stub 和 框架。
             2中的Hello 編譯好以后,我們就可以用RMIC命令來生成殘根Stub
             在Dos窗口里,到Hello.class 所在目錄,運(yùn)行以下命令:
             rmic Hello
             
             命令執(zhí)行完以后,將會(huì)在當(dāng)前目錄生成一個(gè) Hello_Stub.class 這個(gè)就是我們遠(yuǎn)程調(diào)用時(shí)需要的類
           
          參考:
          在RMI中,客戶機(jī)上生成的調(diào)動(dòng)調(diào)用參數(shù)和反調(diào)動(dòng)返回值的代碼稱為殘根。有的書上稱這部分代碼為“主干”。
          服務(wù)器上生成的反調(diào)動(dòng)調(diào)用參數(shù)和進(jìn)行實(shí)際方法調(diào)用調(diào)動(dòng)返回值的代碼稱為框架。
          生成殘根和框架的工具
          Rmic命令行工具(RMI Compiler)
          格式:
          Rmic classname
           
          4、創(chuàng)建一個(gè)服務(wù)器,用于發(fā)布2中寫好的類。
           
              import java.rmi.*;
          public class RMI_Server
          {
              public static void main(String[] args)
              {
                  try
                  {
                      Hello hello = new Hello();                //實(shí)例化要發(fā)布的類
                      Naming.rebind("RMI_Hello", hello);      //綁定RMI名稱 進(jìn)行發(fā)布
                      System.out.println("=== Hello server Ready === ");
                  }
                  catch(Exception exception)
                  {
                      exception.printStackTrace();
                  }
              }
          }
           
          5. 創(chuàng)建一個(gè)客戶程序進(jìn)行RMI調(diào)用。
           
          import java.rmi.*;
          public class RMI_Client {
              public static void main(String[] args) {
                  try
                  {
                     I_Hello hello = (I_Hello) Naming.lookup("RMI_Hello");  //通過RMI名稱查找遠(yuǎn)程對(duì)象
                      System.out.println(hello.SayHello());                        //調(diào)用遠(yuǎn)程對(duì)象的方法
                  } catch (Exception e)
                  {
                    e.printStackTrace();
                  }
              }

          }

          Naming.lookup("RMI_Hello") 其中的參數(shù)“RMI_Hello”只是針對(duì)本機(jī)的RMI查找,如果是異地的RMI調(diào)用請(qǐng)參照  rmi://127.0.0.1:1099/RMI_Hello       端口1099是默認(rèn)的RMI端口,如果你啟動(dòng) rmiregistry 的時(shí)候(見第6點(diǎn))沒有指定特殊的端口號(hào),默認(rèn)就是1099
           
          到此 我們 所有的代碼編寫都完成了,不過不要急著去運(yùn)行,請(qǐng)跟隨第6點(diǎn)去運(yùn)行,因?yàn)閞mi 調(diào)用還會(huì)遇到一些特別的情況,偶花了牛勁,才找到原因的,許多剛用RMI的人,常常被這些問題搞得吐血
           
          6、啟動(dòng)rmiRegistry并運(yùn)行自己的遠(yuǎn)程服務(wù)器和客戶程序。
           1)服務(wù)器的運(yùn)行
              先在DOS下運(yùn)行 rmiregistry     這個(gè)命令是開啟RMI的注冊(cè)服務(wù),開啟以后我們的server程序才能調(diào)用rebing方法發(fā)布我們的類
           
              然后,運(yùn)行我們的server程序  RMI_Server    這里是最容易出錯(cuò)的,參見下面注意事項(xiàng)。
               注意:
                   如果提示找不到Stub類,這個(gè)需要用下面的命令來運(yùn)行
           java.exe -Djava.rmi.server.codebase=file:/E:\MIS_Interface\momo\TestEasy\classes/  RMI_Server
           
          藍(lán)字部分指定了stub類的路徑。
           
            有人會(huì)問,我已經(jīng)把stub 通過-classpath 加到類路徑里面了,為什么還沒有提示這個(gè)錯(cuò)誤呢?原因是這樣的: 這里提示的找不到stub類,不是由你寫的RMI_Server這個(gè)程序引起的,是由rmi注冊(cè)服務(wù)器報(bào)告的異常,也就是我們前面啟動(dòng)的 rmiregistry ,因?yàn)槟銓懙腞MI_Server 要求RMI注冊(cè)服務(wù)器注冊(cè)一個(gè)新的類,自然RMI服務(wù)器必須知道你的類放在哪里,所以我們通過  -Djava.rmi.server.codebase 這個(gè)運(yùn)行參數(shù)來指定
            你也可以通過修改操作系統(tǒng)的classpath 環(huán)境變量 來指定stub的位置,只不過太麻煩
           
          2) 客戶端的運(yùn)行
                直接運(yùn)行RMI_Client  即可  注意 把 Stub 和 接口 I_Hello 加到類路徑里
            
              通常第一次運(yùn)行 客戶端都會(huì)報(bào)一個(gè)錯(cuò)誤:   Access  XXXX 不記得具體的了,反正就是“訪問權(quán)限限制”, 這是因?yàn)镽MI的服務(wù)需要授權(quán),外部程序才能訪問,所以我們要改動(dòng) jre的安全配置文件,來開放權(quán)限,  具體如下:
           
             打開你的jdk目錄下的這個(gè)文件 C:\Program Files\Java\jdk1.5.0_04\jre\lib\security\java.policy
          在文件最后加入下面代碼:
           grant {
                     permission java.net.SocketPermission "*:1024-65535",
                          "connect,accept";
                     permission java.net.SocketPermission "*:80","connect";
                  };
          此代碼,開放了端口的connect訪問權(quán)限
           
          注意 你應(yīng)該修改服務(wù)器那臺(tái)機(jī)子的安全配置文件,也就是你運(yùn)行 rmiregistry 和 RMI_Server的機(jī)子
          另外,很多人修改完以后,仍然報(bào)這個(gè)錯(cuò)誤,多數(shù)情況是由于你沒有修改到正確的jdk 下的文件,而是修改到其他jdk的文件, 我們安裝oracle , Weblogic等等軟件的時(shí)候都會(huì)自帶一個(gè) jdk,他們會(huì)自動(dòng)在操作系統(tǒng)的環(huán)境變量里面 加入jdk的路徑,所以,你先要確定你運(yùn)行服務(wù)器端程序是用哪個(gè)jdk,再修改這個(gè)jdk下的配置文件,確定當(dāng)前jdk的路徑很簡(jiǎn)單  開始 -》運(yùn)行-》rmiregistry 看看這個(gè)DOS窗口標(biāo)題 的路徑,就是你當(dāng)前系統(tǒng)默認(rèn)jdk的路徑了
           
          客戶端正常運(yùn)行以后,就會(huì)出現(xiàn)以下結(jié)果:
          Hello world !!

          這些字符是通過RMI調(diào)用遠(yuǎn)程服務(wù)器的類返回的結(jié)果 

          RMI 實(shí)例

           

          Calculator.java

          import java.rmi.Remote;

          public interface Calculator  extends Remote 


           
              
          public long add(long a, long b)  throws java.rmi.RemoteException ;
           
              
          public long sub(long a, long b)  throws java.rmi.RemoteException ; 
             
              
          public long mul(long a, long b)  throws java.rmi.RemoteException ; 
              
              
          public long div(long a, long b)  throws java.rmi.RemoteException ; 
            
          }
           

          CalculatorClient.java:

          import java.rmi.Naming; 
          import java.rmi.RemoteException; 
          import java.net.MalformedURLException; 
          import java.rmi.NotBoundException; 

          public class CalculatorClient 

              
          public static void main(String[] args) 
                  
          try 
                   Calculator c 
          = (Calculator)
                                     Naming.lookup(
                           
          "rmi://localhost/CalculatorService"); 
                      System.out.println( c.sub(
          43) ); 
                      System.out.println( c.add(
          45) ); 
                      System.out.println( c.mul(
          36) ); 
                      System.out.println( c.div(
          93) ); 
                  }
           
                  
          catch (MalformedURLException murle) 
                      System.out.println(); 
                      System.out.println(
                        
          "MalformedURLException"); 
                      System.out.println(murle); 
                  }
           
                  
          catch (RemoteException re) 
                      System.out.println(); 
                      System.out.println(
                                  
          "RemoteException"); 
                      System.out.println(re); 
                  }
           
                  
          catch (NotBoundException nbe) 
                      System.out.println(); 
                      System.out.println(
                                 
          "NotBoundException"); 
                      System.out.println(nbe); 
                  }
           
                  
          catch (
                      java.lang.ArithmeticException
                                                ae) 

                      System.out.println(); 
                      System.out.println(
                       
          "java.lang.ArithmeticException"); 
                      System.out.println(ae); 
                  }
           
              }
           
          }
           


          CalculatorImpl.java:

          import java.rmi.server.UnicastRemoteObject;

          public class CalculatorImpl extends UnicastRemoteObject implements Calculator


              
          // 這個(gè)實(shí)現(xiàn)必須有一個(gè)顯式的構(gòu)造函數(shù),并且要拋出一個(gè)RemoteException異常 
              public CalculatorImpl() 
                  
          throws java.rmi.RemoteException 
                  
          super(); 
              }
           

              
          public long add(long a, long b) 
                  
          throws java.rmi.RemoteException 
                  
          return a + b; 
              }
           

              
          public long sub(long a, long b) 
                  
          throws java.rmi.RemoteException 
                  
          return a - b; 
              }
           

              
          public long mul(long a, long b) 
                  
          throws java.rmi.RemoteException 
                  
          return a * b; 
              }
           

              
          public long div(long a, long b) 
                  
          throws java.rmi.RemoteException 
                  
          return a / b; 
              }
           
          }
           


          CalculatorRemoteClient.java:


          import java.rmi.Naming; 
          import java.rmi.RemoteException; 
          import java.net.MalformedURLException; 
          import java.rmi.NotBoundException; 

          public class CalculatorRemoteClient 

              
          public static void main(String[] args) 
                  
          try 
                      Calculator c 
          = (Calculator)
                                     Naming.lookup(
                           
          "rmi://10.10.11.209/CalculatorService"); 
                      System.out.println( c.sub(
          43) ); 
                      System.out.println( c.add(
          45) ); 
                      System.out.println( c.mul(
          36) ); 
                      System.out.println( c.div(
          93) ); 
                  }
           
                  
          catch (MalformedURLException murle) 
                      System.out.println(); 
                      System.out.println(
                        
          "MalformedURLException"); 
                      System.out.println(murle); 
                  }
           
                  
          catch (RemoteException re) 
                      System.out.println(); 
                      System.out.println(
                                  
          "RemoteException"); 
                      System.out.println(re); 
                  }
           
                  
          catch (NotBoundException nbe) 
                      System.out.println(); 
                      System.out.println(
                                 
          "NotBoundException"); 
                      System.out.println(nbe); 
                  }
           
                  
          catch (
                      java.lang.ArithmeticException
                                                ae) 

                      System.out.println(); 
                      System.out.println(
                       
          "java.lang.ArithmeticException"); 
                      System.out.println(ae); 
                  }
           
              }
           
          }
           


          CalculatorServer.java:

          import java.rmi.Naming;

          public class CalculatorServer {

             
          public CalculatorServer() {
               
          try {
                 Calculator c 
          = new CalculatorImpl();
                 Naming.rebind(
          "rmi://localhost:1099/CalculatorService", c);
               }
           catch (Exception e) {
                 System.out.println(
          "Trouble: " + e);
               }

             }


             
          public static void main(String args[]) {
               
          new CalculatorServer();
             }

          }


           

          第二個(gè)

          服務(wù)端代碼

          Multi.java
          import java.rmi.*;

          public interface Multi extends Remote {
              
          int multi(int a, int b) throws RemoteException;
          }



          Plus.java
          import java.rmi.*;

          public interface Plus extends Remote{
              
          int plus(int a, int b) throws RemoteException;
          }


          MultiImpl.java
          import java.rmi.*;
          import java.rmi.server.UnicastRemoteObject;

          public class MultiImpl extends UnicastRemoteObject implements Multi{
              
          private String name;
              
          public MultiImpl(String s) throws Exception{
                  
          super();
                  name 
          = s;
              }

              
              
          public int multi(int a, int b) throws RemoteException {
                  System.out.println(
          "Invoke the multiply");
                  
          return (a * b);
              }

          }


          PlusImpl.java
          import java.rmi.*;
          import java.rmi.server.UnicastRemoteObject;

          public class PlusImpl extends UnicastRemoteObject implements Plus {
              
          private String name;
              
          public PlusImpl (String s) throws RemoteException {
                  
          super();
                  name 
          = s;
              }

              
              
          public int plus(int a, int b) throws RemoteException {
                  System.out.println(
          "Invoke the add");
                  
          return (a + b);
              }

          }


          CMSServer.java
          import java.rmi.*;

          public class CMSServer {
              
          public CMSServer(){
                  
          super();
              }

              
              
          public static void main (String[] args) {
                  
          //SYstem.setSecurityManager(new RMISecurityManager());
                  try{
                      
          new CMSServer();
                      MultiImpl mI 
          = new MultiImpl("MultiServer");
                      PlusImpl pI 
          = new PlusImpl("PlusServer");
                      
                      Naming.rebind(
          "pluscxx",pI);
                      Naming.rebind(
          "multicxx",mI);
                      System.out.println(
          "pluscxx and multicxx bound in registry");
                  
                  }
           catch(Exception e) {
                      System.out.println(
          "pluscxx and multicxx err: " + e.getMessage());
                  }

              }

          }


          客戶端代碼

          Multi.java
          import java.rmi.*;

          public interface Multi extends Remote {
              
          int multi(int a, int b) throws RemoteException;
          }


          Plus.java
          import java.rmi.*;

          public interface Plus extends Remote{
              
          int plus(int a, int b) throws RemoteException;
          }


          Frame1.java
          import java.awt.*;
          import java.rmi.*;
          import java.awt.event.*;
          import javax.swing.*;


          public class Frame1 extends JFrame {
              Container container;
              
              
          private JTextField jTextFields[];
              
          private JLabel jLabels[];
              
          private JButton jButton;
              
          private String[] labelsName = {"    Num1""    Num2""    Num3" ,"    plus then multiply" };
              
              
              
          public Frame1() {
                  
          super("sigle client multi server");
                  
          this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  
          //enableEvents(AWTEvent.WINDOW_EVENT_MASK);
                  container = getContentPane();
                  container.setLayout(
          new GridLayout(5,2,10,10));
                  jLabels 
          = new JLabel[4];
                  jTextFields 
          = new JTextField[4];
                  
          int i = 0;
                  
          for(i = 0; i < 4; i++{
                      jLabels[i] 
          = new JLabel(labelsName[i]);
                      jTextFields[i] 
          = new JTextField("jTextField" + i);
                      
          //jTextFields[i].addActionListener(new Handler());
                      container.add(jLabels[i]);
                      container.add(jTextFields[i]);
                  }

                  jButton 
          = new JButton("Compute");
                  container.add(jButton);
                  jButton.addActionListener(
          new Handler());
                  
                  
          this.setSize(new Dimension(400300));
                  
          this.setVisible(true);
              }

              
              
          private class Handler implements ActionListener{
                  
          public void actionPerformed(ActionEvent ae) {
                      
          if(ae.getActionCommand().equals("Compute")) {
                          
          int[] num = new int [3];
                          
          int i = 0;
                          
          for(i = 0; i < 3; i++{
                              num[i] 
          = Integer.parseInt(jTextFields[i].getText());
                          }

                          
          try{
                              Plus p 
          = (Plus)Naming.lookup("pluscxx");
                              System.out.println(
          "Found plus object");    
                              
          int sum = p.plus(num[0], num[1]);
                              System.out.println(
          "Add the first two number");
                              Multi m 
          = (Multi)Naming.lookup("multicxx");
                              System.out.println(
          "Found multi object");
                              
          int multiply2 = m.multi(sum, num [2]);
                              System.out.println(
          "Multi with the last number");
                              System.out.println(
          "result is:" + multiply2);
                              jTextFields[
          3].setText("" + multiply2);
                              
          //container.validate();
                              System.out.println("OK");
                          }
           catch(Exception ex) {
                              System.out.println(ex.getMessage());
                          }

                      }

                  }
                  
              }

              
              
          public static void main(String[] args) {
                  
          new Frame1();
              }

          }



          引用地址:http://blog.csdn.net/tgeh23/archive/2008/03/14/2183746.aspx 

           

          posted on 2008-04-03 13:32 SIMONE 閱讀(1189) 評(píng)論(2)  編輯  收藏 所屬分類: rmi

          FeedBack:
          # re: java RMI 相關(guān)
          2011-12-02 15:56 | 勞資
          你這里好像有點(diǎn)小問題,我自己解決了,不錯(cuò)。  回復(fù)  更多評(píng)論
            
          # re: java RMI 相關(guān)
          2013-08-22 16:32 | ekkny
          @勞資
          服務(wù)端和客戶端分離,怎么通信 ?  回復(fù)  更多評(píng)論
            

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 上高县| 吉木乃县| 南昌市| 松桃| 木兰县| 耿马| 武义县| 五原县| 余干县| 房产| 建阳市| 鹤山市| 兴隆县| 巴里| 凤山县| 壤塘县| 巴马| 青浦区| 河西区| 凤山市| 雷山县| 宁明县| 淮南市| 武山县| 天镇县| 东明县| 浏阳市| 壶关县| 巴青县| 绥中县| 内江市| 顺义区| 广昌县| 丁青县| 澎湖县| 积石山| 扬中市| 汝州市| 乐平市| 麻城市| 乡城县|