javaRMI及简单实例
更新时间:2023-12-29 19:04:01 阅读量: 教育文库 文档下载
远程方法调用实验报告
1.摘要
简单介绍了java中的RMI框架的基本原理及应用,给出了java中创建一个RMI应用的基本步骤。在此基础上设计了一个采用RMI技术实现远程方法调用的实验,客户端调用服务器端的远程对象的方法,获取服务器端的系统时间,将结果返回客户端。此外还对实验结果还进行了分析。
2.实验背景
RMI采用客户/服务器通信方式。在服务器上部署了提供各种服务的远程对象,客户端请求访问服务器上的远程对象的方法。如图1所示,是RemoteServiceClass一个远程对象,它运行在服务器上,客户端请求调用RemoteServiceClass对象的echo()方法。
服务器客户端1.发送参数“hello”对象3.发送返回值“echo.hello”对象远程对象RemoteServiceClass2.调用echo()方法
图1 客户端请求调用服务器上的远程对象的方法 如图2所示,RMI采用代理来负责客户和远程对象之间通过Socket进行通信的细节。RMI框架为远程对象分别生成了客户端代理和服务器端代理。位于客户端的代理类称为存根(Stub),位于服务器端的代理类称为骨架(Skeleton)。
客户端服务器返回值或异常1.发送参数“hello”对象远程对象RemoteServiceClass3.调用echo()方法2.发送被编组的参数远程对象的存根4.发送被编组的返回值或异常远程对象的骨架 图2 RMI框架采用代理来封装通信细节
当客户端调用远程对象的一个方法时,实际上是调用本地存根对象的相应方法。存根对象和远程对象具有同样的接口。存根采用一种与平台无关的编码方式,把方法的参数编码为字节序列,这个编码过程称为参数编组。RMI主要采用java序列化机制进行参数编组。接着,存根把请求信息发送给服务器,服务器端接收到客户端的请求信息,然后由相应的骨架对象来处理这一请求信息,把处理后的返回值或者异常编组后发送给客户。客户端的存根接收到服务器发送过来的编组后的返回值或者异常,再对它进行反编组,就得到调用远程方法的返回结果。
存根与骨架类通过Socket来通信。开发人员无须手工编写客户端的存根类及服务器端的骨架类,它们都由RMI框架创造。在JDK5.0以前的版本中,需要用rmic命令来为远程对象生成静态的代理类(包括存根和骨架类)。而在JDK5.0中,RMI框架会在运行时自动为远程对象生成动态代理类(包括存根和骨架类),从而更彻底封装了RMI框架的实现细节,简化了RMI框架的使用方式。
3.实验环境
使用java语言,平台为MyEclipse。
4.实验方案设计与描述
远程对象所属的类必须实现一个远程接口,由RMI框架负责创建的存根也会实现这个远程接口,在远程接口中声明了可以被客户程序访问的远程方法。实验步骤如下:
(1) 创建远程接口(RemoteService.java):
远程接口中声明了可以被客户程序访问的远程方法。RMI规范要求远程对象所属的类实现一个远程接口,并且远程接口符合以下条件:
1) 直接或者间接继承java.rmi.Remote接口;
2) 接口中的所有方法声明抛出java.rmi.RemoteException. 远程接口RemoteService中声明了echo()和getDate()两个方法,它们都声明抛出RemoteException。 (2) 创建远程类(RemoteServiceClass.java):
远程类就是远程对象所属的类。RMI规范要求远程类必须实现一个远程接口。RemoteServiceClass类就是远程类,它继承了UnicastRemoteObject类,并且实现了RemoteService远程接口。 (3) 创建服务器程序(RemoteServer.java):
服务器程序的一大任务就是向rmiregistry注册表中注册远程对象。以下程序代码注册了一个RemoteServiceClass对象,并且给它命名为“rmi:RemoteService1”:
RemoteService service1=new RemoteServiceClass(\Context namingContext=new InitialContext();
namingContext.rebind(\
服务器程序RemoteServer类的main()方法中,创建了两个RemoteServiceClass对象,然后把它们注册到rmiregistry注册表中,它们的注册名分别为“RemoteService1”和“RemoteService2”。 (4) 创建客户程序(SimpleClient.java):
负责定位远程对象,并且调用远程对象的方法。客户程序SimpleClient类的main()方法中,先获得远程对象的存根对象,然后测试它所属的类,接着调用它的远程方法。
以下程序代码先获得了名为“RemoteService1”的远程对象的存根对象,接着调用存根对象的echo()和getDate()方法:
Context namingContext=new InitialContext();
HelloService
service1=(HelloService)namingContext.lookup(url+\System.out.println(service1.echo(\ System.out.println(service1.getTime());
以下程序代码列举出所有在rmiregistry注册表上注册的远程对象;
NamingEnumeration
System.out.println(e.next().getName());
(5)运行RMI应用
假定实验程序编译后的类文件都位于F:\\MyWorkspace\\workspace\\javaRMI\\bin目录下:
在DOS下转到F:\\MyWorkspace\\workspace\\javaRMI\\bin目录下,先后运行以下命令:
1)使用rmic对RemoteServiceClass.class进行编译,生成代理类RemoteServiceClass_Stub.class,如下:
2)启动rmi注册表,如下:
3)启动服务器端程序,如下:
4)启动客户端程序,如下:
5.实验结果及分析
1、程序运行结果
RemoteServer端的打印结果如下:
RemoteClient端的打印结果如下:
2、结果分析
服务器端的打印结果看,在服务器注册了两个RemoteServiceClass对象,分别为“RemoteService1”和
“RemoteService2”。并且客户端程序分别调用了这两个远程对象的echo()和getDate()方法。而且客户端得到的仅仅是echo()和getDate()方法的返回结果。
在客户端,执行以下代码时:
HelloService
service1=(HelloService)namingContext.lookup(url+\Class stubClass=service1.getClass();
System.out.println(\是\的实例\ Class[] interfaces=stubClass.getInterfaces(); for(int i=0;i System.out.println(\存根类实现了\ 客户端的打印结果为: 由此可见,Context对象lookup()方法返回的是一个名为“RemoteServiceClass_Stub”的代理类的实例,它实现了RemoteService远程接口,这个代理类的实例就是客户程序所访问的RemoteServiceClass远程对象的存根对象。 在客户端,执行以下代码时: System.out.println(service1.echo(\ System.out.println(service1.getTime()); System.out.println(service2.echo(\ System.out.println(service2.getTime()); 客户端的打印结果为: 由此可见,当客户端通过存根调用服务器端的RemoteServiceClass对象的echo()和getDate()方法时,在服务器 端执行对象的echo()和getDate()方法,因此echo()和getDate()方法的第一行语句打印在服务器端输出打印结果,而不会在客户端输出打印结果。客户端得到的仅仅是echo()和getDate()方法的返回结果。 6.小结 通过此次实验,对java中远程方法调用(RMI)框架的基本原理和应用方法有了较好的理解与学习,了解了java中创建一个RMI应用的基本步骤,对RMI有了更深刻的认识。通过对此实验的实现,动手能力也有了一定的提高。 完成此次实验,受益颇丰。 7.参考文献 [1] 孙卫琴.java网络编程精解[M].北京:电子工业出版社,2007 8.附录 (1)远程接口(RemoteService.java): package hello; import java.util.Date; import java.rmi.*; public interface RemoteService extends Remote{ public String echo(String msg) throws RemoteException; public Date getTime() throws RemoteException; } (2)远程类(RemoteServiceClass.java): package hello; import java.util.Date; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class RemoteServiceClass extends UnicastRemoteObject implements RemoteService{ private String name; } public RemoteServiceClass(String name) throws RemoteException { this.name=name; } public String echo(String msg) throws RemoteException{ System.out.println(name+\:调用echo()方法\ return \:\} public Date getTime() throws RemoteException{ System.out.println(name+\:调用getTime()方法\ return new Date(); } (3)服务器程序(RemoteServer.java): package hello; import java.rmi.*; import javax.naming.*; public class RemoteServer { public static void main(String args[]){ try{ RemoteService service1=new RemoteServiceClass(\ RemoteService service2=new RemoteServiceClass(\ Context namingContext=new InitialContext(); namingContext.rebind(\ namingContext.rebind(\ System.out.println(\服务器注册了两个RemoteServiceClass对象:service1,service2\ }catch(Exception e){ e.printStackTrace(); } } } (4) 客户程序(SimpleClient.java): package hello; import java.rmi.*; import javax.naming.*; public class RemoteClient { public static void showRemoteObjects(Context namingContext)throws Exception{ NamingEnumeration } public static void main( String args[] ){ String url=\ try{ System.setProperty(\cy\ System.setSecurityManager(new RMISecurityManager()); Context namingContext=new InitialContext(); RemoteService service1=(RemoteService)namingContext.lookup(url+\ RemoteService service2=(RemoteService)namingContext.lookup(url+\ Class stubClass=service1.getClass(); System.out.println(\是\的实例\ Class[] interfaces=stubClass.getInterfaces(); for(int i=0;i
正在阅读:
javaRMI及简单实例12-29
顶岗实习申请表及实习报告填写指导.09-06
讲解题12-08
常回家看看作文800字06-17
外资威胁我国产业安全05-31
我的班主任管理规定01-06
基础工程复习答案 - 图文03-06
建筑企业应急救援预案06-23
形位公差的代号及标注03-18
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 实例
- javaRMI
- 简单
- 2018年人教版七年级数学下《相交线与平行线》期末复习卷有答案
- 物业服务项目收支情况报告示范文
- 语文版七年级上第13课《空城计》阅读题答案课后练习一课一练
- 计算机错题
- 七年级新生学业水平测试试卷分析报告 - 4
- 八年级英语上册 Module 1 Unit 1 Try not to translate every word教案 外研版
- 学习新课改心得体会
- 高考语文词语拼音
- 中国法治展望
- 学生自主管理的实践与思考
- 英语谚语大全带翻译17
- 电机拖动复习题
- 蔡英文抛台独言论
- 经济学沙盘实验报告 - 如果可以重来
- 各专业监理工程师安全职责
- 初中英语新课程标准测试试题
- 学术道德与学术规范题库最最完整版
- 第十一章习题
- 餐饮协会发言稿
- 苏教版二年级语文下册 17.歌唱二小放牛郎(课堂实录)