一、关于RMI
对于远程,有些时候会想到FTP,HTTP,NFS,IMAP.POP等这些协议,但这些都是主机之间移动文件和数据的信号。另外还有一个是一台主机运行另一台主机的程序,例如Telnet等。而RMI(Remote Method Invocation)正是这个类型。
远程/本地对象区别:远程的对象驻留在不同的虚拟机中,向远程方法传参数和返回结果。
二、RMI机制
对于这种思想的实现机制有三个:
对于简单类型:按值传递
对于实现Remote接口的对象:以远程引用传递,允许接收方法调用远程对象上的方法,这与向本地JAVA方法传递本地引用的方法相似。
对于没有实现Remote接口的对象:按值传递(序列化)
三、RMI分层
服务器程序 | ---------------------------- | 客户端程序 |
骨架 | ---------------------------- | 桩 |
过程引用 | ---------------------------- | 过程引用 |
传输层 | --------Internet--------- | 传输层 |
这样的分层有点像网络的分层关系。
四、实例
1.服务器接口继承Remote
import java.rmi.* ;
import java.rmi.server.*;
public interface TestRMIServer extends Remote{
public String getMessage(String str) throws RemoteException ;
}
2.服务器继承UnicastRemoteObject并间接实现Remote(TestRMIServer接口)
import java.rmi.* ;
import java.rmi.server.* ;
public class TestRMIServerImpl extends UnicastRemoteObject implements TestRMIServer{
public TestRMIServerImpl() throws RemoteException{
super() ;
}
public String getMessage(String str) throws RemoteException {
System.out.println(str) ;
return "success" ;
}
public static void main(String arg[]){
try{
TestRMIServerImpl instance = new TestRMIServerImpl() ;
Naming.rebind("test",instance) ;
System.out.println("Server Registered") ;
}catch(Exception e){
System.out.println(e) ;
}
}
}
3.编写TestClient类为客户端
import java.io.*;
import java.rmi.*;
public class TestClient{
public TestClient(){
try{
BufferedReader input=new BufferedReader(new InputStreamReader(System.in));
String s=input.readLine();
TestRMIServer testServer=(TestRMIServer)Naming.lookup("rmi://127.0.0.1/test");
String str=testServer.getMessage(s);
System.out.print(str);
}catch(Exception e){System.out.println(e);}
}
public static void main(String s[]){
new TestClient();
}
}
4.如下的步骤进行操作
javac 对所有的类进行编译
rmic编译后会产生一个TestRMIServerImpl_Stub.class的文件(放在客户端的)
start rmiregistry看前的转载<转>网络编程RMI ,这个打开会有一个黑屏的。
policytool用的设置一些权限,具体如下
由添加规则项目----》添加权限----》权权限,然后按下面这样选点确认与完成:
5.测试
java TestRMIServerImpl运行服务器
如下图运行客户端
出现上面的东西,这个实验成功了。
6.可能会出现的问题
6.1当忘记开启注册表时,会出现下面的错误:
6.2 当没有开启服务器时,会出现这样的错误:
好了,就这样了,如果用两个或更多机器去调用服务器的方法,在编译后的.class文体中,选三个复制(TestRMIServerImpl_Stub.class,TestRMIServer.class,TestClient.class)过去客户机器就可以了,否则,客户机会错的。