Java RMI地址解析问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java RMI地址解析问题相关的知识,希望对你有一定的参考价值。
我正在尝试重新编写一些基本的设计模式。我只有代码片段,没有完整的运行代码示例。一种叫做代理模式。
我只想通过远程调用方法。这是我的简单代码:
WebService.Java
public class WebService extends UnicastRemoteObject implements IRemote {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
try {
IRemote service = new WebService();
Naming.rebind("RemoteCalculator", service);
} catch (Exception e) {
e.printStackTrace();
}
}
/** No arg default constructor */
public WebService() throws RemoteException { }
/** Methods of remote interface */
@Override
public double getRoot(double v) throws RemoteException {
return Math.sqrt(v);
}
}
...其中IRemote是一个简单的接口,用于扩展远程接口并定义单个示例方法(getRoot(double))的签名。
现在连接到远程的类:
test proxy.Java
public class TestProxy implements Remote{
/**
* @param args
*/
public static void main(String[] args) {
new TestProxy().go(args[0]);
}
public TestProxy() {}
public void go(String ip) {
try {
System.out.println("Trying to lookup for service ...");
IRemote service = (IRemote) Naming.lookup("//" + ip + "/RemoteCalculator");
System.out.println("done");
double d = service.getRoot(5.0);
System.out.println(d);
} catch (Exception e) {
e.printStackTrace();
}
}
}
我正在运行rmiregistry.exe并通过rmic.exe创建我的WebService_Stub.class,如某些文档中所示。本地连接127.0.0.1作为(ip-)参数工作正常。但即使端口(1099)已打开并通过telnet检查,也无法通过互联网进行连接。
当我从命令行开始时:
java net.mypackage.remote.TestProxy 78.2.2.2
它总是给出结果:
试图查找服务...已完成java.rmi.ConnectException:连接拒绝主机:192.168.1.51;嵌套的例外是:java.net.ConnectException:在sun.rmi的sun.rmi.transport.tcp.TCPChannel.createConnection(未知来源)sun.rmi.transport.tcp.TCPEndpoint.newSocket(未知来源)的连接超时.transport.tcp.TCPChannel.newConnection(未知源)位于java.rmi.server.RemoteObjectInvocationHandler的java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unkn own Source)中的sun.rmi.server.UnicastRef.invoke(未知源)。在net.gerdsmeier.remote.TestProxy.main(TestProxy.java:22)net.gerdsmeier.remote.TestProxy.go(TestProxy.java:39)上的$ Proxy1.getRoot(未知来源)调用(未知来源)引起:java.net.ConnectException:在java.net上的java.net.AbstractPlainSocketImpl.connectToAddress(未知来源)java.net.AbstractPlainSocketImpl.doConnect(未知来源)的java.net.PlainSocketImpl.socketConnect(本机方法)连接超时java.net.S java.net.SocksSocketImpl.connect(未知来源)中的.AbstractPlainSocketImpl.connect(未知来源)来自java.net.Socket。(java)的java.net.Socket.connect(未知源)的ocket.connect(未知源),位于sun.rmi.transport.proxy的java.net.Socket。(未知来源)。 sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown Source)的RMIDirectSocketFactory.createSocket(Unknown Source)... 9更多
其中192.168.1.51是我的本地ip-adress(即端口转发工作正常)。
好吧,我猜你的WebService是在NAT之后,你已经在1099上设置了端口转发以进入RMI注册表。这还不够。远程对象将在不同于1099的端口上进行侦听。如果没有设置端口转发到此端口,则永远不会连接,因此在double d = service.getRoot(5.0)
行处有例外。
问题是哪个端口转发?如果您没有指定端口,RMI将随机选择一个高端口。但是您可以使用UnicastRemoteObject构造函数的版本指定端口。因此,您可以选择端口号,执行IRemote service = new WebService([portnumber]);
并在该端口上设置端口转发。
看它是否削减它!
好吧,我已经解决了部分问题。它是服务器存根的逻辑背后:
在服务器端,我们必须通过添加行来添加有关全局主机名的信息
System.setProperty("java.rmi.server.hostname",Util.getGlobalAddress().getHostAddress());
... Util类可能看起来像:
public class Util{
/**
* Finds this computer's global IP address
*
* @return The global IP address, or null if a problem occurred
*/
public static Inet4Address getGlobalAddress()
{
try
{
URLConnection uc = new URL( "http://vallentinsource.com/globalip.php" ).openConnection();
BufferedReader br = new BufferedReader( new InputStreamReader( uc.getInputStream() ) );
return ( Inet4Address ) InetAddress.getByName( br.readLine() );
}
catch( MalformedURLException e )
{
e.printStackTrace();
}
catch( IOException e )
{
e.printStackTrace();
}
return null;
}
}
现在它在一个方向上工作,即客户端调用,如
service.printName("Pete");
在服务器端正常工作。另一方面 ...
d = service.getRoot(5.0);
System.out.println(d);
...在客户端上还没有工作。它不会引发错误,但我们没有得到结果。然而。您可以通过添加客户端ip地址/主机名来修复它:
System.setProperty("java.rmi.client.hostname", "ip.of.client.pc");
但是服务器事先无法知道所有客户端地址。无论如何:这是一种解决方法,在某些情况下可能有所帮助。
以上是关于Java RMI地址解析问题的主要内容,如果未能解决你的问题,请参考以下文章
片段(Java) | 机试题+算法思路+考点+代码解析 2023
RMI 客户端显示 java.rmi.NotBoundException 错误