【问题标题】:Java RMI client and remote server Connection Refused to localhostJava RMI 客户端和远程服务器连接拒绝本地主机
【发布时间】:2016-06-21 16:17:21
【问题描述】:

我在 Java RMI 方面不是很有经验。我正在尝试实现简单的 RMI 通信,但遇到了问题。

这是我的 RMI 客户端

public class MainClientApplication {

    public static final String FILE_NAME_RMI_POLICY = "rmi.policy";
    public static final String RMI_DOMAIN = "mydomain.net";
    public static final String RMI_ENDPOINT = "/MD5Decrypter";
    public static final String PROTOCOL = "rmi://";

    public static void main(String[] args) {
        System.out.println(System.getProperty("user.dir") + File.separator + FILE_NAME_RMI_POLICY);
        System.setProperty("java.security.policy", System.getProperty("user.dir") + File.separator + FILE_NAME_RMI_POLICY);
        String remoteHost = String.format("%s%s%s", PROTOCOL, RMI_DOMAIN, RMI_ENDPOINT);
        System.setSecurityManager(new SecurityManager());
        try {
            ComputeEngine computeEngine = (ComputeEngine) Naming.lookup(remoteHost);
            SwingUtilities.invokeLater(() -> new MainWindow("MD5 Decryption", computeEngine));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}

通讯接口

public interface ComputeEngine extends Remote {
    Object executeTask(Task t) throws RemoteException;
}

我的服务器

public class MainServer {
    public static final int PORT = 1099;
    public static final String RMI_ENDPOINT = "MD5Decrypter";
    public static final String FILE_NAME_RMI_POLICY = "rmi.policy";
    public static final String RMI_DOMAIN = "mydomain.net";
    public static final String PROTOCOL = "rmi://";

   public MainServer() {
    try {
        System.setProperty("java.security.policy", System.getProperty("user.dir") + File.separator + FILE_NAME_RMI_POLICY);
        //System.setProperty("java.rmi.server.hostname", RMI_IP);
        System.setProperty("java.rmi.server.hostname", RMI_DOMAIN);
        System.setSecurityManager(new SecurityManager());
        ComputeEngine computeEngine = new ComputeEngineExecutor();
        //  Naming.rebind(String.format("%s%s:%d/%s", PROTOCOL, RMI_DOMAIN, PORT, RMI_ENDPOINT), computeEngine);
        Naming.rebind(RMI_ENDPOINT, computeEngine);
        System.out.println("Successfully started RMI Server");
    } catch (RemoteException e) {
        e.printStackTrace();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}

    public static void main(String[] args) {
        MainServer mainServer = new MainServer();
    }

}

还有rmi.policy

grant {
    permission java.net.SocketPermission "*:1024-65535", "connect, accept";
    permission java.io.FilePermission "-", "read";
    permission java.net.SocketPermission "*:80", "connect";
};

所以我已经在我的服务器rmiregistry 1099 上启动了 rmiregistry。在调用远程对象方法之前一切正常。

这是我的步骤

假设我的域是 mydomain.net ,我使用静态 IP 将其托管在家里的服务器上。

  1. 在服务器上运行rmiregistry
  2. 在服务器上运行服务器应用程序
  3. 在任何 PC 上运行客户端应用程序
  4. 点击按钮调用远程方法

所以似乎一切都成功连接和绑定,因为如果强制输入无效域、端点或如果 rmiregistry 未启动则被拒绝 - java.rmi.ConnectException 被抛出。

但是当我尝试调用远程对象上的任何方法时,已经成功检索的 BTW 会抛出 java.rmi.ConnectException

java.rmi.ConnectException: Connection refused to host: 127.0.1.1; nested exception is: 
    java.net.ConnectException: Connection refused
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
    at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:130)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
    at com.sun.proxy.$Proxy0.executeTask(Unknown Source)
    at ui.MainWindow.lambda$initGui$0(MainWindow.java:49)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)

据我所知,问题在于它(服务器)强制我连接到本地主机而不是远程。

P.S 在 localhost 上一切正常(客户端和服务器都在一台 PC 上)

请帮忙解决这个问题。

编辑

我忘了告诉我我试图设置java.rmi.server.hostname的属性,在这种情况下启动服务器需要很长时间并以异常结束。

【问题讨论】:

  • 请参阅 RMI 常见问题解答项目 A.1。
  • 感谢您的回答,我已经尝试设置java.rmi.server.hostname,但它的工作方式很奇怪,启动服务器和连接需要很长时间,但最终仍然无法正常工作 - 超时。跨度>
  • 你设置成什么?你必须向我们展示你做了什么。我们看不到你的电脑。注意你必须在服务器 JVM 上设置它。
  • 我已经更新了我的服务器代码。当然,我将它设置在服务器 JVM 上。它似乎冻结在无限循环中。根据wireshark,没什么特别的。
  • 干得好,但是 SO 有很多人试图在客户端设置它,但想知道为什么它不起作用。

标签: java localhost rmi


【解决方案1】:

抛开 127.0.0.1 问题(由 java.rmi.server.hostname 解决),您现在的问题是连接超时。这将由您的防火墙引起。您需要在特定端口上导出远程对象,并且需要在防火墙中打开该 TCP 端口。

【讨论】:

  • 感谢您的回答。我将端口 1099 从外部世界(路由器)转发到我正在运行服务器的本地 PC。有趣的是,如果等待很长时间 aprox。 5 分钟服务器将启动,客户端可以连接到它(名称查找),但又需要很长时间,当我尝试调用远程方法时,它会等待,5 分钟或更长时间后会引发超时异常
  • 端口 1099 是注册表端口。您需要另一个用于远程对象。或者在您的 JVM 中创建注册表并为两者使用 1099。超时是因为所需的端口未打开。您成功连接到注册表,但没有连接到远程对象。听起来您的 DNS 延迟也很大。
  • 非常感谢您的帮助,我也尝试在代码中以编程方式创建注册表,但似乎情况相同。据我所知,客户端和服务器将使用随机端口相互通信,我不想打开路由器中的所有端口。请您提供任何示例如何为远程对象指定通信端口。
  • 叹息。他们使用随机端口除非您将远程对象导出到特定端口,我已经告诉过您这样做两次。
猜你喜欢
  • 1970-01-01
  • 2012-05-25
  • 1970-01-01
  • 1970-01-01
  • 2014-05-31
  • 2023-02-12
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多