【问题标题】:Java RMI Connect Exception: Connection refused to host / timeoutJava RMI 连接异常:连接拒绝主机/超时
【发布时间】:2012-01-19 02:12:07
【问题描述】:

我正在开发 RMI 命令行游戏,但每当我尝试使用我的服务时,我都会收到如下错误:

java.rmi.ConnectException: Connection refused to host: 192.168.56.1; nested exception is: 
    java.net.ConnectException: Connection timed out: connect

这是我Server的主要课程:

public class RMIWar {

    public static void main(String[] args) throws RemoteException, MalformedURLException  {
        try {
            Controle obj = new Controle(4);
            Registry reg = LocateRegistry.createRegistry(1099);
            System.out.println("Server is ready");
            reg.rebind("CtrlServ", obj);
        }
        catch (Exception e) {
            System.out.println("Error: " + e.toString());
        }
    }
}

我的Client 课程的主要内容:

public class RMIWarClient {
    public static void main(String[] args) throws RemoteException, MalformedURLException, NotBoundException  {
        try {
            Registry registry = LocateRegistry.getRegistry("localhost");
            ControleInt ctrl = (ControleInt) registry.lookup("CtrlServ");
            System.out.println("CtrlServ found...\n");
            BioRMI bio = new BioRMI(null, 5,5,5);
            ctrl.thRegister("Test", bio.atk, bio.def, bio.agi);

        }

        catch (Exception e) {
            System.out.println("Error: " + e);
        }
    }
}

有什么建议吗?

【问题讨论】:

    标签: java exception jakarta-ee rmi


    【解决方案1】:

    测试您的 1099 端口是否可用(这意味着被防火墙阻止)。此外,您没有提及您使用的是什么操作系统,以及您是否在执行服务器之前启动了注册表。

    此 RMI tutorial 解释:

    在启动计算引擎之前,您需要启动 RMI 注册表。 RMI 注册表是一个简单的服务器端引导程序命名 使远程客户端能够获得对 初始远程对象。

    默认情况下,注册表在端口 1099 上运行,就像您的一样。 如教程所述,只需打开命令提示符(在 Windows 上)或 shell 终端(在类 UNIX 操作系统上)并输入:

    对于 Windows(如果 start 不可用,请使用 javaw):

    start rmiregistry
    

    Solaris 操作系统或 Linux

    rmiregistry &
    

    更新

    我注意到,按照 Oracle 的教程和我之前的一个项目,在 Server 类中,您没有将对象导出到 RMI 运行时。 然后你应该编辑这些行:

    Controle obj = new Controle(4);
    Registry reg = LocateRegistry.createRegistry(1099);
    System.out.println("Server is ready");
    reg.rebind("CtrlServ", obj);
    

    到:

    Controle obj = new Controle(4);
    Controle stub = (Controle) UnicastRemoteObject.exportObject(obj, 0);
    Registry reg = LocateRegistry.createRegistry(1099);
    System.out.println("Server is ready");
    reg.rebind("CtrlServ", stub);
    

    因为教程报告:

    静态 UnicastRemoteObject.exportObject 方法导出 提供远程对象,以便它可以接收对其的调用 来自远程客户端的远程方法。

    此外,如果您将同一主机用于 RMI 调用,则 Client 类中不需要它:

    Registry registry = LocateRegistry.getRegistry("localhost");
    

    只需调用:

    Registry registry = LocateRegistry.getRegistry();
    

    因为 Oracle 报告:

    LocateRegistry.getRegistry 的无参数重载合成了一个 对本地主机和默认注册表上的注册表的引用 端口,1099。您必须使用具有 int 参数的重载,如果 注册表是在 1099 以外的端口上创建的。

    【讨论】:

    • 这些都不会导致连接超时。
    • @EJP 关于连接超时,我写道:“测试你的 1099 端口是否可用”。这意味着检查端口是否可用或是否有防火墙。我关于 rmiregistry 开始的注释是因为 OP 没有写任何关于此的内容,并且因为有时服务的不执行是连接被拒绝的原因。如果Client想要执行Server的某个方法,但是Server没有和服务一起在本地运行,Client永远不会执行该方法。
    • 我在 Mac 和 Windows 7 上对此进行了测试。还在没有 Av / 防火墙的 Win XP 虚拟机上进行了尝试,得到了相同的结果。我已将 getRegistry("localhost") 更改为 getRegistry("localhost",1099) ,现在我收到了 java.rmi.UnmarshalException: error unmarshalling return;嵌套异常是:java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException
    • @Sprite 我明白了。按照 Oracle 的教程并查看您的代码,在 Server 类中,您没有使用“Controle stub = (Controle) UnicastRemoteObject.exportObject(obj, 0) 导出到 Controle 对象(称为“obj”)的 RMI 运行时;"在注册表创建之前。然后,您应该编辑行“reg.rebind("CtrlServ", obj);"到 "reg.rebind("CtrlServ", stub);"
    • 这些都不相关。 OP 正在调用LocateRegistry.createRegistry(1099),因此:(a) 他不需要在命令行启动它; (b) 他不需要担心端口不是1099; (c) 端口可用,否则他会得到一个包装在 ExportException 中的 BindException。不执行服务不会导致“连接超时”;不导出远程对象也不行;如果您的课程没有扩展UnicastRemoteObject,您只需致电exportObject()
    【解决方案2】:

    请注意端口,因为它们可能会被防火墙阻止,例如,如果您在工作或大学等安全区域工作,管理员可能已经实施了一些保护措施...

    【讨论】:

      【解决方案3】:

      我看不出您是如何从该代码中获得该异常的。根据代码,您的服务器和客户端在同一主机上运行,​​并且您不会在同一主机内获得连接超时。

      因此,假设这不是您的真实代码并且您正在查找正确的注册表(getRegistry() 的主机参数),我会问 192.168.56.1 是否是您希望在网络拓扑中看到的 IP 地址。这是一个内部 LAN 地址,如果您的客户端在 LAN 之外,它应该尝试连接到更公共的 IP 地址。如果地址不是你所期望的,我推荐你item A.1 on the RMI FAQ

      【讨论】:

        【解决方案4】:

        我在这里java.rmi.ConnectException: Connection refused to host: 127.0.1.1;Cannot connect to Tomcat's MBeanServer via jconsole in Java6 描述了我的解决方案。该问题是一个基本的网络问题,但也可能发生在其他人身上。

        【讨论】:

          猜你喜欢
          • 2014-11-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-01
          • 2012-09-10
          • 1970-01-01
          • 2021-08-12
          相关资源
          最近更新 更多