在不同的网络上使用RMI

时间:2015-02-11 15:08:49

标签: java rmi

来宾的计算机可以位于服务器以外的网络上。 如果不是,一切都没问题,但是当他是的时候,会抛出ConnectException

你知道为什么吗?

额外信息: 我将端口从1099(默认)修改为80以尝试解决问题,不起作用。 使用Wireshark,我看到客人正在使用端口50740.我不明白为什么,以前从未见过这个号码。 我使用.policy文件授予所有权限。

编辑: 我已经有了.bat定义的服务器IP。我的客户端开头也有Locate.createRegistry(80);。是否足以让客户端使用端口80?

奇怪的是我可以尝试登录(我的应用程序在启动时要求登录),看看我的凭据是否正常。然后,如果客户端不在同一网络上,则会抛出ConnectException

2 个答案:

答案 0 :(得分:1)

  

我将端口从1099(默认)修改为80以尝试解决问题,不起作用。使用Wireshark,我看到客人正在使用端口50740.我不明白为什么,以前从未见过这个号码。

当RMI客户端想要与远程对象通信时,通常首先联系端口1099上的RMI注册表,询问它在哪里可以找到目标对象。注册表回复一个包含目标对象地址(主机名和端口号)的存根,然后客户端可以连接到目标主机和端口以与远程对象通信。

如果在调用UnicastRemoteObject超类构造函数或静态exportObject方法时未指定显式端口号,则RMI将选择要使用的随机可用端口号。这可能是50740来自的地方 - 它是目标对象正在侦听的端口,而不是注册表。

但是目标对象地址的第二个元素是主机名 - 如果对象在注册表中列在127.0.0.1:50740这样的地址,那么另一台机器上的客户端将最终尝试连接到该对象在错误的地方(在客户端的 localhost而不是服务器上)。解决方案是确保对象在注册表中以适当的主机名或可从客户端解析的IP地址绑定 - 理论上这应该是自动发生的,但有时RMI会出错。解决方案是将系统属性传递给RMI服务器(绑定注册表中目标对象的进程)

java -classpath .... -Djava.rmi.server.hostname=192.168.0.1 com.example.MyRmiServer

192.168.0.1替换为客户端计算机用于与服务器通信的正确IP地址。

答案 1 :(得分:0)

您需要在固定端口号上导出远程对象,并在防火墙中打开该端口。最容易使用的端口是1099,因为它已经保留了,但它要求您通过LocateRegistry.createRegistry()而不是rmiregistry在JVM中启动注册表,这样您就可以共享端口。 / p>