logo资料库

吉林大学软件学院服务计算概论第二次作业.docx

第1页 / 共15页
第2页 / 共15页
第3页 / 共15页
第4页 / 共15页
第5页 / 共15页
第6页 / 共15页
第7页 / 共15页
第8页 / 共15页
资料共15页,剩余部分请下载后查看
服务计算概论 实验报告 (二) 学院:软件学院 姓名: 学号:
服务计算第 2 次作业 一、实验题目 利用 LocaleRegistry 和 Context 实现远程对象调用 二、实验内容  利用 java.rmi.registry.LocateRegistry 实现 RMI 调用;  利用 javx.naming.Context 实现 RMI 调用;  思考和解答代码中的一些关键问题; 注:JDK1.3 版本或更低的版本支持 java.rmi.Naming,JDK1.3 以后将命名服务 API 整合到 JNDI 中,javax.naming.Context 声明了 注册、查找,以及注销对象的方法。 三、实验要求 (1)对关键代码解释清楚; (2)远程对象功能自定; (3)逻辑清楚,表述完整、准确; (4)要有必要截图。
四、实验步骤 1.实验环境 Java 环境(jdk 1.8),Eclipse IDE,Windows 10 2.RMI 的原理 2.1 RMI 的定义 RMI(Remote Method Invocation,远程方法调用),是允许运 行在一个 Java 虚拟机的对象调用运行在另一个 Java 虚拟机上的对象 的方法。 这两个虚拟机可以是运行在相同计算机上的不同进程中, 也可以是运行在网络上的不同计算机中。 Java RMI(Java Remote Method Invocation,Java 远程方法调 用)是 Java 编程语言里一种用于实现远程过程调用的应用程序编程 接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程 方法调用特性使 Java 编程人员能够在网络环境中分布操作。RMI 的 宗旨就是尽可能简化远程接口对象的使用。 2.2 RMI 的优点 按照 RMI 规则设计程序,在编程时不需要注重在 RMI 之下的网络 细节,如 TCP 和 Socket。任意两台计算机之间的通讯完全由 RMI 负 责。调用远程计算机上的对象就像本地对象一样方便。 RMI 有以下几个优点: (1)面向对象: RMI 可将完整的对象作为参数和返回值进行传 递,而不仅仅是预定义的数据类型;
(2)便于移动:RMI 可将属性从客户机移动到服务器,或者从 服务器移动到客户机; (3)安全性:RMI 使用 Java 内置的安全机制保证下载执行程序 时用户系统的安全; (4)便于编写和使用:RMI 使得 Java 远程服务程序和访问这些 服务程序的 Java 客户程序的编写工作变得简单。为了实现 RMI 的功 能必须创建远程对象任何可以被远程调用的对象必须实现远程接口。 但远程接口本身并不包含任何方法。因而需要创建一个新的接口来扩 展远程接口。新接口将包含所有可以远程调用的方法。远程对象必须 实现这个新接口,由于新的接口扩展了远程接口,实现了新接口,就 满足了远程对象对实现远程接口的要求,所实现的每个对象都将作为 远程对象引用。 2.3 RMI 的结构和调用步骤 2.3.1 RMI 构架 在 RMI 应用程序中,我们编写两个程序,一个服务器程序(驻留 在服务器上)和一个客户端程序(驻留在客户端上)。在服务器程序 内部,创建一个远程对象,并为该客户端提供该对象的引用(使用注 册表)。客户端程序请求服务器上的远程对象并尝试调用其方法。 下图显示了 RMI 应用程序的体系结构:
图 1 RMI 应用程序的体系结构 该架构的组件结构如下: (1)传输层(Transport Layer):连接客户端和服务器。它管 理现有的连接,并建立新的连接; (2)存根(Stub):存根是远程对象在客户端的表示(代理)。 它驻留在客户端系统中,充当客户端程序的网关; (3)骨架(Skeleton):驻留在服务器端的对象,存根与该骨架 通信以将请求传递给远程对象; (4)RRL(Remote Reference Layer,远程参考层):管理客户 端对远程对象的引用的层。 2.3.2 RMI 注册表 RMI 提供了一个简单的命名服务,叫做 RMI 注册表。RMI 注册表是 所有服务器对象放置在其上的命名空间。每次服务器创建一个对象时, 它都会使用 bind()或 reBind()方法向 RMI 注册表注册该对象。这些 使用称为绑定名称的唯一名称进行注册。
下图展示了调用过程: 图 2 RMI 程序的调用过程 为了调用远程对象,客户端需要该对象的引用。客户端使用其绑 定名称(使用 lookup()方法)从注册表中获取对象。 2.3.3 远程方法调用过程 远程方法调用的基本过程如下,在实际实现过程中细节可能有所 不同: (1)创建远程接口并声明远程方法,继承 java.rmi.Remote (Client 和 Server 需要共享这个接口); (2)创建远程接口的实现类,这个类必须继承自 java.rmi.server.UnicastRemoteObject; (3)为远程接口生成存根(Stub)和骨架(Skeleton)文件, 使用 rmiregistry 程序开启服务器 RMI 注册表; (4)编写 Server,绑定端口,注册对象; (5)编写 Client,监听端口并查找对象。
3. 编写代码实现 RMI 调用 3.1 利用 java.rmi.registry.LocateRegistry 实现 RMI 调用 3.1.1 实现过程 (1)定义远程接口 Hello.java 远程接口提供了特定远程对象所有方法的描述,客户端与此远程 接口进行通信。首先定义一个名为 Hello 的远程接口,并且有一个 printMsg()的方法,代码如下: import java.rmi.Remote; import java.rmi.RemoteException; public interface Hello extends Remote { void printMsg() throws RemoteException; } 由于远程调用期间可能出现网络问题,因此可能会发生名为 RemoteException 的异常,需要抛出该异常。 (2)开发远程对象类 ImplExample.java 在实现前面步骤中创建的远程接口时,可以单独编写一个实现类, 也可以直接在服务器程序实现这个接口,为了体现业务逻辑分离的思 想,编写一个单独的类来实现该接口,该程序实现的功能是输出一条 语句,代码如下: public class ImplExample implements Hello { public void printMsg() { System.out.println("This is an example RMI program. @Copyright dwk55171106"); } } (3)开发服务器程序 Server.java RMI 服务器程序的功能是实现远程接口或扩展实现类。在 RMI 服 务器程序中,创建一个远程对象并将其绑 RMIregistry。实现服务器 程序的代码如下:
import java.rmi.registry.Registry; import java.rmi.registry.LocateRegistry; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; public class Server extends ImplExample { public Server() {} public static void main(String args[]) { try { ImplExample obj = new ImplExample(); (1) Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0); (2) (3) Registry registry = LocateRegistry.getRegistry(); registry.bind("Hello", stub); (4) (5) System.out.println("Server ready"); } catch (Exception e) { System.err.println("Server exception: " + e.toString()); (6) e.printStackTrace(); (7) } } } 其中行(2)使用 exportObject()方法导出远程对象,行(3) 使用 getRegistry()方法获取 RMI 注册表,行(4)使用名为 Registry 的类的 bind()方法将创建的远程对象绑定到 Registry。此方法可将 表示绑定名称和导出对象的字符串作为参数传递。 (4)开发客户端程序 Client.java 客户端程序的作用是获取远程对象并使用此对象调用所需的方 法,实现客户端程序的代码如下: import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class Client { private Client() {} public static void main(String[] args) { try { Registry registry = LocateRegistry.getRegistry(null); (1) Hello stub = (Hello) registry.lookup("Hello"); stub.printMsg(); (3) (2) System.out.println("Remote method invoked"); } catch (Exception e) { System.err.println("Client exception: " + e.toString()); (4) e.printStackTrace(); } } }
分享到:
收藏