为什么RMI本地客户端使用非本地IP连接RMI本地服务器

8
我们正在使用客户端/服务器RMI通信在同一台计算机上进行(因此所有IP都应该是localhost)。
我们启动注册表(使用默认端口1099)
registry = LocateRegistry.createRegistry(port);
并将一些对象导出到RMI注册表
Naming.rebind(“//”+“localhost”+“:”+ port +“/”+ name,object);
从另一个进程中检索一些对象(请记住,所有内容都在localhost上运行)
MyRemoteObject ro =(MyRemoteObject)Naming.lookup(“//”+“localhost”+“:”+ port +“/”+ name);
当您以本地区域网络工作开始运行应用程序,并且在过程中禁用网络连接时,问题会发生。如果您运行应用程序并且LAN正常工作,则不会弹出任何问题,如果您运行应用程序并且LAN不工作,则不会弹出任何问题。只有在运行应用程序时更改LAN时才会发生这种情况。
执行Naming.lookup()方法时抛出的异常是:
java.lang.RuntimeException:java.rmi.ConnectIOException:创建到:192.168.x.x的连接时出现异常;嵌套异常是: java.net.NoRouteToHostException:无法路由到主机:连接
调试了一下,我发现RemoteObject($ Proxy0) - > RemoteObjectInvocationHandler - > UnicastRef2 - > LiveRef - > TCPEndpoint的主机IP(例如:192.168.x.x)而不是“ localhost”或127.0.0.1(这是我想要的内容)。 liveRef对象的isLocal布尔值始终为false。
我不知道是否够清楚。对不起!!!
你有什么建议吗?
我的尝试:
我尝试了以下解决方案
使用-Djava.rmi.server.hostname = localhost参数运行jvm
重新定义RMIServerSocketFactory以每次返回127.0.0.1。(TCPEndpoint具有192.168.x.x IP,isLocal始终为false)
在URI中不带主机调用rebind和lookup。这意味着localhost。
但是这些都没有起作用。
欢迎任何建议。
3个回答

9

java.rmi.server.hostname应该能解决问题。你在服务器上设置了它,对吧?

如果java.rmi.server.hostname=localhost不起作用,那么尝试使用java.rmi.server.hostname=127.0.0.1java.rmi.server.hostname=::1怎么样?


1
+1 可能会让人困惑的是:你必须将此选项提供给 RMI 服务器,而不是客户端。为什么?如果你省略它,服务器将绑定到公共 IP 地址(而不是本地主机),而客户端足够聪明,可以找到它。 - Aaron Digulla
如果只有IPv6处于活动状态怎么办?127.0.0.1会自动转换为::1吗? - gorootde
如果只有IPv6处于活动状态,那么仅使用“localhost”就可以很好地解决问题。您也可以尝试将其设置为“::1”,看看是否有效。据我所知,“127.0.0.1”对IPv6网络堆栈没有意义。没有自动翻译。 - Neeme Praks

0

您可以尝试使用以下属性启动服务器:-Djava.rmi.server.hostname=localhost

另请参见第3.5.4节

这是因为服务器绑定到一个接口,即127.0.0.1或192.168.x.x


0

抱歉,各位。是我的错误。

正如你们所指出的,我将“java.rmi.server.hostname=localhost”参数设置为客户端进程。当我将该参数设置为运行RMI服务器的进程时,它就像魔法般运行。

非常感谢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接