下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

java中如何正确的使用远程接口

作者:课课家教育     来源: http://www.kokojia.com点击数:1072发布时间: 2016-02-29 20:10:42

标签: java违例java基础类java构建器

大神带你学编程,欢迎选课

  服务器必须包含一个扩展了UnicastRemoteObject的类,并实现远程接口。这个类也可以含有附加的方法,但客户只能使用远程接口中的方法。这是显然的,因为客户得到的只是指向接口的一个句柄,而非实现它的那个类。

  必须为远程对象明确定义构建器,即使只准备定义一个默认构建器,用它调用基础类构建器。必须把它明确地编写出来,因为它必须“掷”出RemoteException违例。

java中如何正确的使用远程接口_java违例_java基础类_课课家

  下面列出远程接口PerfectTime的实施过程:

  //: PerfectTime.java

  // The implementation of the PerfectTime

  // remote object

  package c15.ptime;

  import java.rmi.*;

  import java.rmi.server.*;

  import java.rmi.registry.*;

  import java.net.*;

  public class PerfectTime

  extends UnicastRemoteObject

  implements PerfectTimeI {

  // Implementation of the interface:

  public long getPerfectTime()

  throws RemoteException {

  return System.currentTimeMillis();

  }

  // Must implement constructor to throw

  // RemoteException:

  public PerfectTime() throws RemoteException {

  // super(); // Called automatically

  }

  // Registration for RMI serving:

  public static void main(String[] args) {

  System.setSecurityManager(

  new RMISecurityManager());

  try {

  PerfectTime pt = new PerfectTime();

  Naming.bind(

  "//colossus:2005/PerfectTime", pt);

  System.out.println("Ready to do time");

  } catch(Exception e) {

  e.printStackTrace();

  }

  }

  } ///:~

  在这里,main()控制着设置服务器的全部细节。保存RMI对象时,必须在程序的某个地方采取下述操作:

  (1) 创建和安装一个安全管理器,令其支持RMI。作为Java发行包的一部分,适用于RMI唯一一个是RMISecurityManager。

  (2) 创建远程对象的一个或多个实例。在这里,大家可看到创建的是PerfectTime对象。

  (3) 向RMI远程对象注册表注册至少一个远程对象。一个远程对象拥有的方法可生成指向其他远程对象的句柄。这样一来,客户只需到注册表里访问一次,得到第一个远程对象即可。

  1. 设置注册表

  在这儿,大家可看到对静态方法Naming.bind()的一个调用。然而,这个调用要求注册表作为计算机上的一个独立进程运行。注册表服务器的名字是rmiregistry。在32位Windows环境中,可使用:

  start rmiregistry

  令其在后台运行。在Unix中,使用:

  rmiregistry &

  和许多网络程序一样,rmiregistry位于机器启动它所在的某个IP地址处,但它也必须监视一个端口。如果象上面那样调用rmiregistry,不使用参数,注册表的端口就会默认为1099。若希望它位于其他某个端口,只需在命令行添加一个参数,指定那个端口编号即可。对这个例子来说,端口将位于2005,所以rmiregistry应该象下面这样启动(对于32位Windows):

  start rmiregistry 2005

  对于Unix,则使用下述命令:

  rmiregistry 2005 &

  与端口有关的信息必须传送给bind()命令,同时传送的还有注册表所在的那台机器的IP地址。但假若我们想在本地测试RMI程序,就象本章的网络程序一直测试的那样,这样做就会带来问题。在JDk 1.1.1版本中,存在着下述两方面的问题(注释⑦):

  (1) localhost不能随RMI工作。所以为了在单独一台机器上完成对RMI的测试,必须提供机器的名字。为了在32位Windows环境中调查自己机器的名字,可进入控制面板,选择“网络”,选择“标识”卡片,其中列出了计算机的名字。就我自己的情况来说,我的机器叫作“Colossus”(因为我用几个大容量的硬盘保存各种不同的开发系统——Clossus是“巨人”的意思)。似乎大写形式会被忽略。

  (2) 除非计算机有一个活动的TCP/IP连接,否则RMI不能工作,即使所有组件都只需要在本地机器里互相通信。这意味着在试图运行程序之前,必须连接到自己的ISP(因特网服务提供者),否则会得到一些含义模糊的违例消息。

  ⑦:为找出这些信息,我不知损伤了多少个脑细胞。

  考虑到这些因素,bind()命令变成了下面这个样子:

  Naming.bind("//colossus:2005/PerfectTime", pt);

  若使用默认端口1099,就没有必要指定一个端口,所以可以使用:

  Naming.bind("//colossus/PerfectTime", pt);

  在JDK未来的版本中(1.1之后),一旦改正了localhost的问题,就能正常地进行本地测试,去掉IP地址,只使用标识符:

  Naming.bind("PerfectTime", pt);

  服务名是任意的;它在这里正好为PerfectTime,和类名一样,但你可以根据情况任意修改。最重要的是确保它在注册表里是个独一无二的名字,以便客户正常地获取远程对象。若这个名字已在注册表里了,就会得到一个AlreadyBoundException违例。为防止这个问题,可考虑坚持使用rebind(),放弃bind()。这是由于rebind()要么会添加一个新条目,要么将同名的条目替换掉。

  尽管main()退出,我们的对象已经创建并注册,所以会由注册表一直保持活动状态,等候客户到达并发出对它的请求。只要rmiregistry处于运行状态,而且我们没有为名字调用Naming.unbind()方法,对象就肯定位于那个地方。考虑到这个原因,在我们设计自己的代码时,需要先关闭rmiregistry,并在编译远程对象的一个新版本时重新启动它。

  并不一定要将rmiregistry作为一个外部进程启动。若事前知道自己的是要求用以注册表的唯一一个应用,就可在程序内部启动它,使用下述代码:

  LocateRegistry.createRegistry(2005);

  和前面一样,2005代表我们在这个例子里选用的端口号。这等价于在命令行执行rmiregistry 2005。但在设计RMI代码时,这种做法往往显得更加方便,因为它取消了启动和中止注册表所需的额外步骤。一旦执行完这个代码,就可象以前一样使用Naming进行“绑定”——bind()。

赞(12)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程