`
阅读更多
1、RMI概述
RMI(Remote Method Invocation)
RMI是分布式对象软件包,方便了JAVA应用程序在多台计算机之间的通信。
必须在jdk1.1以上
RMI用到的类:
java.rmi.Remote
所有可以被远程调用的对象都必须实现该接口
java.rmi.server.UnicastRemoteObject
所有可以被远程调用的对象都必须扩展该类
优点:
方便了JAVA应用程序在多台计算机之间的通信。
只要按照RMI规则设计程序,可以不必再过问在RMI之下的网络细节了,如:TCP和Socket等等。
任意两台计算机之间的通讯完全由RMI负责。调用远程计算机上的对象就像本地对象一样方便。
创建远程方法调用的5个步骤:
1、定义一个继承了远程接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常。
2、定义一个实现该接口的类。
3、使用RMIC程序生成远程实现所需的残根和框架。存根(stub)和框架(skeleton)
4、创建一个客户程序和服务器进行RMI调用。
5、启动Registry并运行自己的远程服务器和客户程序。
对应上面的步骤分析:
1.
所有的RMI操作都应放到try-catch块中:
由于任何远程方法调用实际上要进行许多低级网络操作,因此网络错误可能在调用过程中随时发生.
2.
实现该接口的类(服务端类):必须继承UnicastRemoteObject类。
扩展java.rmi.server.UnicastRemoteObject
UnicastRemoteObject顾名思义,是让客户机与服务器对象实例建立一对一的连接。
3.
在RMI中,客户机上生成的调动调用参数和反调动返回值的代码称为残根。有的书上称这部分代码为“主干”。
服务器上生成的反调动调用参数和进行实际方法调用调动返回值的代码称为框架。
生成残根和框架的工具
Rmic命令行工具(RMI Compiler)
格式:
Rmic classname
4.
第五步、用RmiRegistry找到远程对象
这是一个使用工具,维护文本名和远程对象之间的映射,可以进行远程访问。

如下面的实例:
若手动运行的话,要用:
rmic RemotePrinterImpl  生成Stub 和 Skeleton,它们实际上是远程调用的底层的实现。
start rmiregistry       启动rmi的注册程序,使文本名和远程对象之间的映射,实现远程访问. 
java RemotePrinterImpl  启动服务器
java PrintClient        启动客户端
===========================在eclipse中创建RMI实例=================================
(一)创建接口端:
1.
在eclpse中创建一个java project-->project's layout选择分开放置.
2.
在project中,添加一个package-->选择,新建一个 Remote Interface(不是简单的interface),默认完成.
3.
在接口在写入各抽象方法,都要用throws RemoteException.
如下:
public interface RemotePrinter extends Remote { 
 public int submitJob(String text) throws RemoteException; 
 public boolean isComplete(int jobID) throws RemoteException; 
 public String getPrinterStatus() throws RemoteException;  
}
(二)创建服务端:
1.
在eclpse中创建一个java project-->project's layout选择分开放置-->切换到project分页,添加接口的project包-->默认完成.
2.
在project中,添加一个package-->新建一个JAVA类-->其父类要选择:UnicastRemoteObject-->其实现的接口,要添加刚创建的接口-->默认完成.
3.
添加自己的构造方法带throws RemoteException.
4.
对接口的方法,进行实现.
5.
在main方法中:
用try..catche,防止有异常.
进行注册: Registry r=LocateRegistry.getRegistry();
进行绑定:r.bind("printer", new RemotePrinterImpl());
输入成功提示:System.out.println("printer server is ready");
6.
生成子根:
点击 server的整个project package,右键-->RMI-->Enabel subs ... -->系统会自动生成子根.
(三)创建客户端:
1.
在eclpse中创建一个java project-->project's layout选择分开放置-->切换到project分页,添加接口的project包-->默认完成.
2.
在project中,添加一个package-->新建一个JAVA类,默认完成.
3.
在main方法中:
用try..catche,防止有异常.
设置安全管理;
连接服务端,利用接口实例化服务端对象;
用新建实例调用各方法进行运用.
如下:
System.setSecurityManager(new RMISecurityManager());
RemotePrinter jprinter=(RemotePrinter)Naming.lookup("rmi://localhost/printer");
int jobID=jprinter.submitJob("hello word");
System.out.println("submitted job's ID: "+jobID);
System.out.println("is complete ? "+jprinter.isComplete(jobID));
System.out.println("printer status: "+jprinter.getPrinterStatus());
(四)
如何运行:
1.
在RMI工具键,下拉选择start locale Registry; -->弹出提示,选择NO.
2.
右键点击SERVER类,用RMI application进行运行--->第一次运行时,会弹出配置对话框-->切换到RMI VM Properties -->选择java.rmi.server.codebase-->add-->点击compute from classpath-->完成即可.
3.
右键点击CLIENT类,用RMI application进行运行--->第一次运行时,会弹出配置对话框-->切换到RMI VM Properties -->选择java.security.policy-->add-->create-->选择CLIENT的project包-->完成即可.
--->上面记录具体是否有错,明晚再试.

===============================将RMI实例打包运行==================================
0.
先要运行:
C:\Program Files\Java\jre1.5.0_09\bin>start rmiregistry
==>
如何避免要进行此步后,才能进行启动SERVER.
原因:
因为在server端的代码中用: Registry r=LocateRegistry.getRegistry();
而要让程序自动启动RMI注册程序: Registry r=LocateRegistry.createRegistry(端口号);
而在客户端: -->也应该添加相应的端口
RemotePrinter jprinter=(RemotePrinter)Naming.lookup("rmi://localhost:8888/printer");
1.
对于SERVER端:
1.1
打包时,也要一起打上接口的包.不能单独只打SERVER包.
1.2
写运行bat时,只须:
java -Xmx350M -jar  -Djava.rmi.server.codebase=file:///D:/printer/server/server.jar server.jar
分析:
-Djava.security.policy不是必要的, -->服务器不用去连接其它人,是其它人来连接它的.所以不用安全验证.
而-Djava.rmi.server.codebase则是必要的-->否则会出现找不到存根的错.-->codebase,是给客户端连接用的.所以一定要.

2.
对于CLIENT端: -->可放在任何放不用改路径.
第一种设置方法:
1)
打包时,也要一起打上接口的包.不能单独只打client包.
2)
写运行bat时:
java -Xmx350M -jar -Djava.security.policy=./etc/security.policy client.jar
分析:
-Djava.security.policy=./etc/security.policy:用来通过RMI的安全验证.否则不能进入.

双保险的方式是:
用上面的方式,同时用以下的方式(设置MANIFEST.MF以及添加相应的目录和jar包),两者同时存在.
以下方式,可以不用.
第二种设置方法:  -->须加设置且加lib文件夹,但
2.1
打包时,不用也一起打上接口的包.
1.2
写运行bat时,只须:
java -Xmx350M -jar -Djava.security.policy=./etc/security.policy client.jar
分析:
-Djava.security.policy是必要的,
而-Djava.rmi.server.codebase则不是必要的.
1.3
同时要修改MANIFEST.MF:
Manifest-Version: 1.0
Class-Path: lib/interface.jar                 -->添加项,且在目录下建lib目录,放接口的包
Main-Class: demo.rmi.print.client.PrintClient

===============================另一实例===============================
-------------RMIInterface.java:
public interface RMIInterface extends Remote {
 public int submitJob(String text) throws RemoteException;
 public boolean isComplete(int jobID) throws RemoteException;
 public String getPrinterStatus() throws RemoteException; 
}
-----------RMIServer.java
public class RMIServer extends UnicastRemoteObject implements RMIInterface {
 private static Logger logger=Logger.getLogger(RMIServer.class.getName());
 
 public RMIServer() throws RemoteException
 {
  try
  {    
RMIConfig rmiconfig=new RMIConfig("etc/RMIconfig.cfg");
Registry r=LocateRegistry.createRegistry(Integer.parseInt(rmiconfig.getPort()));
String RMIurl="rmi://"+rmiconfig.getHostName()+":"+rmiconfig.getPort()+"/"+rmiconfig.getServiceName();
   logger.info("rebind name :"+RMIurl);   
   Naming.rebind(RMIurl,this);
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
 }
 public String getPrinterStatus() throws RemoteException {
  System.out.println("requested the printer status");
  return "OK";
 }
 public boolean isComplete(int jobID) throws RemoteException {
  System.out.println("requested the job status");
  return true;
 }
 public int submitJob(String text) throws RemoteException {
  System.out.println("submitted job "+text);
  return 0;
 }
 public static void main(String[] args) {
  try
  {
   File f=new File("etc/log4j.properties");
   if(!f.exists())
   {
    logger.fatal("the log4j.properties is not exist");
    System.exit(0);
   }
   PropertyConfigurator.configure("etc/log4j.properties");
   RMIServer server=new RMIServer();
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
 }
}
---------------RMIClient.java
public class RMIClient {
 private static Logger logger=Logger.getLogger(RMIClient.class.getName());
 public RMIClient()
 {
  try
  {
   logger.info("Start RMI Client ......");
   RMIConfig rmiconfig=new RMIConfig("etc/RMIconfig.cfg");
   
   System.setSecurityManager(new RMISecurityManager());
   String rmiUrl="rmi://"+rmiconfig.getHostName()+":"+rmiconfig.getPort()+"/"+rmiconfig.getServiceName();
   RMIInterface jprinter=(RMIInterface)Naming.lookup(rmiUrl);
   int jobID=jprinter.submitJob("hello word");
   System.out.println("submitted job's ID: "+jobID);
   System.out.println("is complete ? "+jprinter.isComplete(jobID));
   System.out.println("printer status: "+jprinter.getPrinterStatus());
   
  }
  catch(Exception e)  
  {
   
  }
 }
 public static void main(String[] args) {
  
  try
  {
   File file=new File("etc/log4j.properties");
   if(!file.exists())
   {
    logger.fatal("the log4j.properties is not exist");
    System.exit(0);
   }
   PropertyConfigurator.configure("etc/log4j.properties");
   
   RMIClient client=new RMIClient();
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
 }
}
分享到:
评论

相关推荐

    java rmi java rmi

    java rmi java rmijava rmi javajava rmi java rmi rmi

    java RMI技术实现的网络聊天室

    java RMI技术实现的网络聊天室 编译通过,很完整的。代码很有参考价值

    基于JAVA RMI的聊天室

    采用JAVA rmi,带图形界面,完全由自己实现的聊天室,具备基本的聊天功能,可以自己扩充功能

    javaRMI反序列化漏洞验证工具

    检测javaRMI反序列化漏洞

    java RMI简单Demo

    java RMI

    java RMI实现代码

    java RMI实现代码。分为客户端和服务器端,有清楚的代码注释。

    Java RMI 简单示例

    Java RMI 简单示例

    java rmi远程调用

    最近在学习代理模式,用到了java rmi远程调用,包含服务端和客户端,之前一直没有接触过,学习了java rmi远程调用,一方面可以了解代理模式,一方面熟悉java低层的远程

    JavaRMI.pdf

    JavaRMI.pdf

    Java RMI.pdf

    《Java RMI》一书的英文版本,With Java RMI, you'll learn tips and tricks for making your RMI code excel. This book provides strategies for working with serialization, threading, the RMI registry, ...

    javaRMI完整版.pdf

    javaRMI完整版.pdf

    Java RMI中文规范

    这是本人搜集整理的Java RMI规范,中文版,经过排版 共包括10个章节,2个附录

    java rmi上传文件

    在这次的项目中,对于客户端与服务器之间的通信,想了许多办法,由于做的是富客户端应用,最终将技术选定在了RMI和Java-sockets两种之间,其中RMI的灵活性不高,客户端和服务器端都必须是java编写,但使用比较方便,...

    原创的JavaRMI项目

    这是原创的最简单的Java RMI入门项目,内含二个Eclipse项目,一是服务器端,二是客户端。非常简单,只看其中的注释就能理解(当然先要知道什么是RMI了),只供入门用。 这是用Java 1.7编辑的,如果你用的版本低,则...

    JavaRMI的原理和实现方法

    JavaRMI的原理和实现方法 分布式对象计算 来源于青岛大学学报

    分布式程序java 实验名称 基于Java RMI的C/S编程实验

    实验名称 基于Socket的C/S编程实验 实验名称 基于Java RMI的C/S编程实验

    java rmi HelloWorld版(源码)

    java rmi 调用实例及详细说明,详细可参见博客:http://blog.csdn.net/fufengrui/article/details/9855865

    JAVARMI实例[文].pdf

    JAVARMI实例[文].pdf

    JavaRMI分布式编程心得

    网络上绝大多数关于Java RMI分布式编程的资料真的很久、很古老了, 我也是偶尔看到别人的文章,自己动手做实验才总结的一些心得与例子, 希望能够帮到那些有用的人!

Global site tag (gtag.js) - Google Analytics