Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java RMI无法连接到远程服务器_Java_Rmi_Security Policy - Fatal编程技术网

Java RMI无法连接到远程服务器

Java RMI无法连接到远程服务器,java,rmi,security-policy,Java,Rmi,Security Policy,我最近一直在使用RMI,当我设法使它在locahost上工作时,我在尝试使用远程服务器时遇到了各种各样的问题。以下是我尝试运行的基本代码: 服务器: public class RmiServer extends UnicastRemoteObject implements RmiServerIntf { public static final String MESSAGE = "Hello world"; public RmiServer() throws RemoteExce

我最近一直在使用RMI,当我设法使它在locahost上工作时,我在尝试使用远程服务器时遇到了各种各样的问题。以下是我尝试运行的基本代码:

服务器:

public class RmiServer extends UnicastRemoteObject implements RmiServerIntf {
    public static final String MESSAGE = "Hello world";

    public RmiServer() throws RemoteException {
    }

    public String getMessage() {
    return MESSAGE;
    }

    public static void main(String args[]) {
        System.out.println("RMI server started");

        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new RMISecurityManager());
            System.out.println("Security manager installed.");
            } else {
                   System.out.println("Security manager already exists.");
            }

            try {
                    LocateRegistry.createRegistry(1099);
                    System.out.println("java RMI registry created.");
            } catch (RemoteException e) {
                    e.printStackTrace();
            }

            try {
                    RmiServer obj = new RmiServer();

                    Naming.rebind("rmi://localhost/RmiServer", obj);

                    System.out.println("PeerServer bound in registry");
            } catch (Exception e) {
                    e.printStackTrace();
            }
      }
}
远程类接口:

public interface RmiServerIntf extends Remote {
    public String getMessage() throws RemoteException;
}
客户:

public class RmiClient { 
    RmiServerIntf obj = null; 

    public String getMessage() { 
        try { 
            obj = (RmiServerIntf)Naming.lookup("rmi://54.229.66.xxx/RmiServer");
            return obj.getMessage(); 
        } catch (Exception e) { 
            e.printStackTrace(); 
            return e.getMessage();
        } 
    } 

    public static void main(String args[]) {
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new RMISecurityManager());
        }

        RmiClient cli = new RmiClient();

        System.out.println(cli.getMessage());
    }
}
rmi.policy文件:

grant {
permission java.security.AllPermission;
};
我编译了这些类并为服务器创建了一个存根。然后,我将客户机、存根、接口和策略放在我的机器上,将服务器、存根、接口和策略放在远程机器上。远程服务器是Linux机器,我使所有文件都可执行。我还在本地防火墙上添加了允许端口1099的规则,并打开了远程机器上的所有端口

在此之后,我导航到远程计算机上的服务器目录,并插入以下命令:

java -Djava.security.policy=rmi.policy RmiServer
这并没有给我带来问题,所以我回到本地机器并输入

java -Djava.security.policy=rmi.policy RmiClient
我等待,等待,然后我得到错误消息:

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

我昨天一整天都在与这些连接错误作斗争,这就是我所能做到的。我确信只有一件非常小的事情我仍然做错了,但我就是找不到它是什么。

这可能无法解决您的问题,但我在Linux上遇到了类似的JPPF(通过Java RMI)问题。解决方案是确保客户端计算机上的临时端口范围仅覆盖客户端本地防火墙允许的端口。例如,如果防火墙允许外部计算机连接端口48000到64000,请确保临时端口范围也在48000到64000之间。试试看,让我们知道会发生什么

System.setProperty("java.rmi.server.hostname","10.0.3.73");

请在服务器端代码中使用上述语句,然后再次尝试从远程客户端连接。它对我有效

您能使用telnet等连接到远程机器上的任何端口吗?是的,我对其他类型的连接没有问题。我使用端口22、80或11111(JPPF)时没有问题。您的客户端代码的ip地址与“连接被拒绝”消息的ip地址不同,因此以下内容可能会有所帮助:+1但注册表根本不会“切换连接”。在连接阶段不会调用它。实际情况是,除非在导出远程对象时指定端口,否则它将在临时端口侦听。我不是专门讨论注册表,而是讨论用于为该注册表提供服务的底层网络机制。在引擎盖下,RMI使用
ServerSocket
Socket
ServerSocket
绝大多数情况下都会侦听特定端口,在与客户端进行初始握手后,将与该客户端的所有后续通信转交给侦听完全不同的临时端口号的
Socket
,不管您选择了哪个端口号来监听
ServerSocket
,您都错了。ServerSocket返回本地端口号与侦听端口号相同的套接字。因此,如果在固定端口上导出RMI对象,则指向该对象的所有连接都将使用该端口。短命诗人出现在RMI中的原因是,在导出时没有提供非零端口号,例如,通过super(int-port)。我确实犯了错误。我第一次接触RMI是在一个项目上,该项目使用了定制的ServerSocket和套接字工厂,它们的行为与我描述的“移交”方式相同-我们这样做是为了让对手更难劫持特定的客户端连接-但这已经有一段时间了,所以我将其误认为是默认的RMI行为。我甚至不认为这是可能的,除非在临时端口上使用了额外的侦听套接字。我认为你的回忆也错了。我还建议你修正你的答案。它对你的IP地址有效,因为那是你的IP地址之一。没有什么能保证对每个人都有效。