`
xiaobian
  • 浏览: 587957 次
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多
作为整个产品供应链中的一部分,现代企业的企业信息资源广泛分布在各种网络体系中,企业必须能够处理这些分布的信息资源,这使得分布式企业应用成为构建企业信息环境的必然需求。RMI是使用最广泛的分布式对象系统之一,本文举例介绍了分布式企业计算的基本模式及如何应用RMI 来开发分布式的企业应用。
  
  一、客户/服务端模式
  客户/服务模式通过使用一个应用程序(客户)和另一个程序(服务端)交换数据。在客户/服务模式的应用中,通常使用低层次的Socket来开发,使用Socket来开发客户/服务端模式意味着我们必须自己设计一种包含客户端和服务端都统一的命令集的协议,使得客户端和服务端能够通过这个协议来通信。
  
  二、分布式对象模式
  分布式对象系统是一个对象集合,通过定义很完善的统一接口来分隔开请求服务(客户端)和功能服务(服务端)。在分布式对象模式里,客户端发送一个消息到一个对象,由对象解释这个消息,然后决定应该由什么服务来完成,这个服务、方法或选择可能是被一个对象或是被一个Broker来完成的。
  
  三、RMI
  RMI是一个分布式对象模式。由于不需要设计协议使得使用RMI开发分布式程序比使用socket更加容易。在RMI里,设计者就象在调用一个本地类的方法一样,而实际上是在调用的时候相应的参数被发送到远端的对象后被解释,最后结果返回给调用者,下面本文通过开发一个文件交换程序来介绍RMI的应用。这个应用允许客户端从服务端交换(或下载)所有类型的文件。第一步是定义一个远程的接口,这个接口指定的签名方法将被服务端提供和被客户端调用。
  1.定义一个远程接口
  FileInterface.java代码如下:
  import java.rmi.Remote;
  import java.rmi.RemoteException;
  public interface FileInterface extends Remote {
    public byte[] downloadFile(String fileName) throws
    RemoteException;
  }
  接口FileInterface提供了一个downloadFile方法,然后返回一个相应的文件数据。
  2.实现远程的接口
  类FileImpl继承于UnicastRemoteObject类。这显示出FileImpl类是用来创建一个单独的、不能复制的、远程的对象,这个对象使用RMI默认的基于TCP的通信方式。FileImpl.java代码如下:
  import java.io.*;
  import java.rmi.*;
  import java.rmi.server.UnicastRemoteObject;
  public class FileImpl extends UnicastRemoteObject
   implements FileInterface {
    private String name;
    public FileImpl(String s) throws RemoteException{
     super();
     name = s;
    }
    public byte[] downloadFile(String fileName){
     try {
       File file = new File(fileName);
       byte buffer[] = new byte[(int)file.length()];
       BufferedInputStream input = new
     BufferedInputStream(new FileInputStream(fileName));
       input.read(buffer,0,buffer.length);
       input.close();
       return(buffer);
     } catch(Exception e){
     System.out.println("FileImpl: "+e.getMessage());
       e.printStackTrace();
       return(null);
     }}}
  3.编写服务端
  (1)创建并安装一个RMISecurityManager实例。
  (2)创建一个远程对象的实例。
  (3)使用RMI注册工具来注册这个对象。
  FileServer.java 代码如下:
  import java.io.*;
  import java.rmi.*;
  public class FileServer {
    public static void main(String argv[]) {
     if(System.getSecurityManager() == null) {
  System.setSecurityManager(new RMISecurityManager());
     }
     try {
       FileInterface fi = new FileImpl("FileServer");
       Naming.rebind("//127.0.0.1/FileServer", fi);
     } catch(Exception e) {
       System.out.println("FileServer: "+e.getMessage());
       e.printStackTrace();
     }}}
  声明Naming.rebind("//127.0.0.1/FileServer", fi) 中假定了RMI注册工具(RMI registry )使用并启动了1099端口。如果在其他端口运行了RMI注册工具,则必须在这个声明中定义。例如,如果RMI注册工具在4500端口运行,则声明应为:
  Naming.rebind("//127.0.0.1:4500/FileServer", fi)
  另外我们已经同时假定了我们的服务端和RMI注册工具是运行在同一台机器上的。否则需要修改rebind方法中的地址。
  4.编写客户端
  客户端可以远程调用远程接口(FileInterface)中的任何一个方法。无论如何实现,客户端必须先从RMI注册工具中获取一个远程对象的引用。当引用获得后,方法downloadFile被调用。在执行过程中,客户端从命令行中获得两个参数,第一个是要下载的文件名,第二个是要下载的机器的地址,在对应地址的机器上运行服务端。FileClient.java 代码如下:
  import java.io.*;
  import java.rmi.*;
  public class FileClient{
    public static void main(String argv[]) {
     if(argv.length != 2) {
      System.out.println("Usage: java FileClient fileName machineName");
      System.exit(0);
     }
     try {
       String name = "//" + argv[1] + "/FileServer";
       FileInterface fi = (FileInterface) Naming.lookup(name);
       byte[] filedata = fi.downloadFile(argv[0]);
       File file = new File(argv[0]);
       BufferedOutputStream output = new
  BufferedOutputStream(new FileOutputStream(file.getName()));
       output.write(filedata,0,filedata.length);
       output.flush();
       output.close();
     } catch(Exception e) {
       System.err.println("FileServer exception: "+ e.getMessage());
       e.printStackTrace();
     }}}
  5.运行程序
  为了运行程序,我们必须使用rmic来编译生成stubs和skeletons:prompt>rmic FileImpl。这将会生成FileImpl_Stub.class和FileImpl_Skel.class两个文件。stub是客户端的代理,而skeleton是服务端的框架。服务端和客户端采用javac来编译(如果服务端和客户端在两个不同的机器,则必须复制一个FileInterface接口)。
  使用rmiregistry或者start rmiregistry 命令来运行RMI注册工具到window系统默认的端口上:
  prompt> rmiregistry portNumber
  RMI注册工具运行之后,需要运行服务FileServer,因为RMI的安全机制将在服务端发生作用,所以必须增加一条安全策略:
  grant {
  permission java.security.AllPermission "", "";
  };
  为了运行服务端,需要有除客户类(FileClient.
  class)之外所有的类文件。确认安全策略在policy.txt文件之后,使用如下命令来运行服务器。
  prompt> java -Djava.security.policy=policy.txt FileServer
  为了在其他的机器运行客户端程序,需要一个远程接口(FileInterface.class)和一个stub(FileImpl_Stub.class)。 使用如下命令运行客户端:
  prompt> java FileClient fileName machineName
  这里fileName是要下载的文件名,machineName 是要下载的文件所在的机器(也是服务端所在的机器)。如果全部通过的话,当客户端运行后,则这个文件将被下载到本地
  • javarmi.rar (54.7 KB)
  • 描述: JAVARMI 规范
  • 下载次数: 79
分享到:
评论
5 楼 sds123456 2008-04-11  
我在windows下跑了一下, 步骤和上面写的一样, 但执行 java -Djava.security.policy=policy.txt FileServer  时候老是报错:


C:\Documents and Settings\Michael Xu\桌面>java - Djava.security.policy=policy.txt  FileServer

FileServer: Connection refused to host: 127.0.0.1; nested exception is:
        java.net.ConnectException: Connection refused: connect
java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested excepti
on is:
        java.net.ConnectException: Connection refused: connect
        at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
        at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185
)
        at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
        at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
        at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
        at java.rmi.Naming.rebind(Naming.java:160)
        at FileServer.main(FileServer.java:11)
Caused by: java.net.ConnectException: Connection refused: connect
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
        at java.net.Socket.connect(Socket.java:516)
        at java.net.Socket.connect(Socket.java:466)
        at java.net.Socket.<init>(Socket.java:366)
        at java.net.Socket.<init>(Socket.java:179)
        at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirect
SocketFactory.java:22)
        at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMaster
SocketFactory.java:128)
        at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569)
        ... 6 more


4 楼 andrii 2007-06-07  
EJB,不知道到底多大的项目才会用EJB?为什么又有<J2EE without EJB>
3 楼 murainwood 2007-06-07  
曾经在某个项目中曾经用过这种方法。因为客户传输的文件都不大,单个不超过10M,所以这种办法还是比较省力的。但是做大文件测试就不适合了
2 楼 xiaobian 2007-06-06  
这个我也不知道。 RMI 不是被用来传递数据的。 这个只是一个例子而以。 可能让你错解了。
1 楼 murainwood 2007-06-05  
小文件可以,大文件怎么办?
遇到一两个G的文件,又怎么办?堆溢出

相关推荐

    rmi远程调用读取文件

    在这个场景中,“rmi远程调用读取文件”指的是通过RMI机制,使得一个JVM中的程序能够请求另一个JVM上的程序读取并返回文件内容。这种方式在分布式系统中非常常见,可以用于数据共享、文件服务等应用。 RMI的基本...

    RMI远程过程调用(远程文件管理)

    java jdk1.8;...掌握远程过程调用原理,基于java RMI进行远程编程和控制。要求定义远程接口类及实现类:定义相应的处理方法;客户端利用RMI实现远程调用服务。同时,在在两台机器之间验证结果正确。

    RMI远程文件传输

    在"RMI远程文件传输"这个场景中,我们主要探讨如何利用RMI技术来实现在网络环境中传输文件。 RMI的基础是Java序列化机制,它允许将Java对象转换为字节流,通过网络发送,然后在接收端恢复为原来的对象。文件传输的...

    RMI远程调用代码及使用方法

    ### RMI远程调用代码及使用方法 #### 一、RMI简介 远程方法调用(Remote Method Invocation,简称RMI)是Java平台提供的一种分布式计算技术,它允许开发人员在不同的Java虚拟机(JVM)之间进行对象的远程调用。通过...

    rmi远程接口调用

    在实际应用中,RMI可以用于构建分布式应用、分布式数据库系统、分布式文件系统等。但是,RMI也存在一些限制,如不支持多线程调用、性能问题以及安全性考虑等,因此在现代Java开发中,通常会结合其他技术,如JMS、JAX...

    javarmi来实现远程下载文件

    在本场景中,我们利用Java RMI来实现实时的远程文件下载功能。下面将详细阐述如何使用Java RMI来实现这一目标。 首先,我们需要理解Java RMI的基本工作原理。RMI系统包含两部分:服务器端(Server)和客户端...

    动态代理与RMI远程调用

    在提供的`动态代理与RMI远程调用.ppt`中,可能会详细解释这两个概念,通过PPT的讲解和实例,可以更直观地理解动态代理和RMI的工作原理。同时,`src`目录下的源码文件则提供了具体的实现示例,读者可以通过阅读代码,...

    RMI实现远程文件传输实例

    在你提供的实例中,“RMI实现远程文件传输”是利用RMI来传输“KEY文件”的具体应用。 首先,理解RMI的基本概念: 1. 远程对象:这是在远程服务器上运行并可以通过网络访问的对象。它们需要实现特定的接口,这个接口...

    使用rmi进行远程调用

    - `server.properties`:服务器配置文件,可能包含RMI注册表的端口号和绑定名称。 - `build.xml`或`pom.xml`:构建脚本,用于编译和打包项目。 了解RMI对于开发Java分布式应用至关重要,它简化了不同节点间的通信,...

    rmi文件下载与上传代码

    RMI(Remote Method ...总的来说,这个RMI项目提供了一个基础的文件管理系统,展示了如何利用RMI在Java环境中实现远程文件操作。通过学习和理解这个项目,开发者可以深化对RMI的理解,掌握分布式系统开发的关键技能。

    rmi 远程调用 实现客户端之间会话

    文件列表中的“程序说明.doc”可能是对整个RMI实现的详细说明,包括代码示例和步骤解释。而“RMILab”可能是一个包含实验代码的文件夹,可能包含了服务器端和客户端的Java源代码,以及运行和测试RMI应用程序所需的...

    分布式 RMI远程调用

    分布式RMI(Remote Method Invocation)远程调用是一种在分布式系统中实现对象间通信的技术,它允许一个对象在某个进程中调用另一个位于不同进程或者不同计算机上的对象的方法,从而实现跨网络的对象交互。...

    RMI远程时钟调用 java程序

    在这个“RMI远程时钟调用 java程序”中,我们看到的是一个利用RMI实现的远程时钟服务,该服务可以在用户指定的时间间隔内更新显示时间。 1. **RMI基础概念**:RMI是Java平台的核心特性之一,用于构建分布式应用程序...

    三种方式实现java远程调用(rmi),绝对可用

    在提供的压缩包文件中,"三种方式(原始方式_spring_jndi)实现java远程调用(rmi)"包含了相关的示例代码,帮助开发者理解并实践这三种RMI实现方法。在MyEclipse或其他Java开发环境中导入这些代码,可以进行调试和...

    基于rmi的远程控制

    10. **部署与配置**:RMI应用需要正确配置JVM的RMI服务,包括设置RMIREGISTRY端口、JDK的`.policy`文件以指定安全策略,以及可能的防火墙或安全组规则。 在“基于RMI的远程控制”项目中,开发者可能创建了一个包含...

Global site tag (gtag.js) - Google Analytics