用RMI和CORBA开发JAVA分布式程序
RMI(远程方法调用)和CORBA(通用对象调用代理架构)是两个最重要,并广泛应用的分布对象系统架构。每个架构都有优劣,这两个架构没应用到从电子商务到医保系统等不同的领域。两者中任何一个被应用到项目中都是个困难的工作。这篇文章大概介绍了RMI和CORBA,并演示了如何开发一个远程下载文件的实例。
。介绍分布式对象系统
。介绍RMI和CORBA
。
。演示如何用RMI和CORBA从远程主机传输文件
。比较CORBA和RMI
C/S模式
客户机/服务器模式是服务器和客户机交换信息进行分布计算的一种形式。在这个模式里,客户机和服务器都用同一种语言—它们都理解的协议进行通信。
C/S模式有不同的方式,典型的应用是低层SOCKET开发。用SOCKET开发意味着我们必须设计一套协议,C/S双方能相互通信的一系列命令集。一个例子就是HTTP协议,提供了一个GET方法,为了得到传输的文档,C/S都必须实现。
分布式模式
基于系统的分布式对象是通过定义好的接口来隔离客户端请求和服务器端服务的对象集。
数据请求和执行是分开的,这是C/S模式与分布式模式的主要区别。
在一个分布式模型里,客户端发送消息给一个对象,这个对象判断消息决定哪种服务执行。
服务或者方法,SELECTION被对象或者代理来执行。RMI和CORBA就是这个模型的例子。
RMI
RMI是能使你很容易地开发分布市对象的系统。RMI比SOCKETS开发容易地多,不需要定义协议。用RMI,开发者会认为调用本地类的本地方法,实际上是从远程传输,翻译,并把结果传递到本地。
RMI应用起步
开发RMI,包括以下几个步骤:
1 定义一个远程接口
2 应用远程接口
3 服务器端开发
4 客户端开发
5 生成骨干代码,启动RMI注册,服务器,客户端
下面我们讲述每一步的具体实现。
例子:文件传输应用
允许传输任何类型的文件到远程主机。第一步定义描述方法的远程接口。
定义远程接口
代码一是下载文件的远程接口。接口FileInterface 提供了一个下载文件的方法,返回文件的字节集。
Code Sample 1: FileInterface.java import java.rmi.Remote; import java.rmi.RemoteException; public interface FileInterface extends Remote { public byte[] downloadFile(String fileName) throws RemoteException; }
注意:
为了客户端能装载包含远程接口的远程对象,接口必须定义为Public
必须扩展Remote接口,为了实现远程对象
接口里的每个方法必须抛出RemoteException异常
应用远程接口
下一步是实现接口FileInterface ,一个简单的应用在代码二。
注意为了实现接口FileInterface ,类FileImpl 必须扩展 UnicastRemoteObject 。
这说明类 FileImpl 创建一个单一,不能复制的通过 TCP 传输的 RMI 对象,
Code Sample 2: 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); } } }
服务器端开发
第三步是开发服务器端,有三个步骤:
1 创建RMISecurityManager 实例并安装它
2 创建一个远程对象的实例
3 用 RMI 注册对象。
Code Sample 3: 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 注册是运行在缺省端口1099。如果RMI注册是在其它端口,此句应改为: Naming.rebind("//127.0.0.1:4500/FileServer", fi)
客户端开发
下一步就是开发客户端。客户端远程调用远程接口定义的任何方法。为了实现,客户端必须先获得RMI注册的远程对象的实例。一旦获得,下载文件方法就别调用。如代码4。这个应用中,客户端接收两个命令行参数。
Code Sample 4: 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(); } } }
运行这个应用
为了运行这个应用,我们必须先生成骨干码,然后编译服务器端,客户端代码,RMI注册,最后开始应用。
为了生成骨干码,我们用RMIC命令:
命令行: rmic FileImpl
将生成两个文件: FileImpl_Stub.class 和 FileImpl_Skel.class . 客户端代理和服务端骨干。
下一步,编译SERVER,CLIENT代码
最后,开始RMI注册,运行。
命令行 > rmiregistry portNumber
注册完成后,就可以开始服务器端应用。如果应用了RMI安全管理,你需要一个安全策略来处理。下面就是一个简单的security policy: grant { permission java.security.AllPermission "", ""; };
注意:这只是一个简单的安全策略,如果比较重要的应用,你需要用更严格的安全策略。
拷贝所有的类除了客户端类。确认安全策略在policy.txt后,用下面命令开始服务器端应用。
命令行 > java -Djava.security.policy=policy.txt FileServer
为了在不同的机器开始客户端应用,你需要拷贝 (FileInterface.class ) 和(FileImpl_Stub.class ).
命令行 > java FileClient fileName machineName

|