从Internet上看到的RMI,但不是从局域网看到的

时间:2013-05-21 16:06:56

标签: java rmi lan hostname

这是我在stackoverflow中的第一篇文章,我正在尝试使用RMI实现聊天但是我被卡住了,我避免使用rmiregistry,一切都在localhost上绑定得很好,但我需要它可以从互联网,端口转发,防火墙下来,实际上我可以通过互联网检索一个对象,我已经使用

System.setProperty("java.rmi.server.hostname","ruso.89.x.ignorelist.com");

然后我的NameServer.java绑定到该IP,但是我通过localhost失去了所有访问权限,现在让我解释一下。这是NameServer.java的代码

public class NameServer
{
   public static void main (String args [] )
   {
    String direscucha = "ruso.89.x.ignorelist.com";
    int puertonombres = 5000;
    try{

        System.setProperty("java.rmi.server.hostname", direscucha);          
        System.setProperty("java.security.policy", "C:\\Users\\Antonio\\Desktop\\DistributedChat\\myServer.policy");
        System.setSecurityManager(new RMISecurityManager());
        NameService ns = new NameService();
        Registry reg=LocateRegistry.createRegistry(puertonombres);
        reg.rebind("ns",ns);
        while(true){}
    }catch(Exception e){
        System.out.println(e);
    }
  }
}

这是我的政策文件:

grant {
permission java.security.AllPermission;
permission java.net.SocketPermission "ruso.89.x.ignorelist.com:*", "connect,resolve,accept";
permission java.net.SocketPermission "localhost:*", "connect,resolve,accept";
permission java.net.SocketPermission "127.0.0.1:*", "connect,resolve,accept";
};

然后我需要ChatServer.java来运行,这需要ns并将自己绑定到它,因此可以找到ChatServer,问题是当我从局域网外部使用它时我可以让服务器运行!但是当我使用localhost时我得到了一个例外

ChatServer.java(Snippet)

public void work ()
{
    String direscucha = "ruso.89.x.ignorelist.com";        
    int puertonombres = 5000;
    System.setProperty("java.rmi.server.hostname", direscucha); //Binds to the Public IP
    System.setProperty("java.security.policy", "C:\\Users\\Antonio\\Desktop\\DistributedChat\\myClient.policy"); //marca la politica
    System.setSecurityManager(new RMISecurityManager()); //Ejecuta el RMISecurityManager
    try
    {                                    
        String[] list = Naming.list("//localhost:5000/"); //Debugging
        System.out.println("Tamanyo: "+list.length);      
        for(int i=0; i<list.length; i++)                  
            System.out.println(list[i]);
        NameService_Stub ns =  (NameService_Stub) Naming.lookup("rmi://localhost:5000/ns");

        ns.rebind (conf.getServerName(), this);
        System.out.println("Servidor registrado::");
    }
    catch (java.rmi.ConnectException e)
    {
        System.out.println (e);
        System.exit(-1);            
    }
    catch (Exception e)
    {
        System.out.println(e);
        System.exit(-1);
    }

所以当ServerChat现在注册时,任何用户都可以执行ChatClient.java从NameService中检索ChatServer的名称然后连接,但是还没有得到,因为我无法管理ChatServer工作。我的第一个问题是,在设置hostname属性时,localhost被阻止但是没有提到,之后我虽然可能是路由器NAT的问题,但它可能是吗?

例外:

java.rmi.ConnectException: Connection refused to host: ruso.89.x.ignorelist.com; nested exception is:
java.net.ConnectException: Connection refused: connect

客户端和服务器策略文件完全相同。 使用WireShark查看发生的情况,发送SYN并收到ACK,收到RST。 我已经烧掉了所有的想法,有什么建议吗?

1 个答案:

答案 0 :(得分:0)

  

我使用

获得了这个      

System.setProperty( “java.rmi.server.hostname”, “ruso.89.x.ignorelist.com”);

     

然后我的NameServer.java绑定到那个IP

不,不。这是一种常见的误解,但不正确。除非您提供ServerSockets,否则RMI始终将其RMIServerSocketFactory绑定到0.0.0.0。 java.rmi.server.hostname的作用是将其值嵌入存根(基本上不是InetAddress.getLocalHost()返回的值)。

   while(true){}

您不需要通过这样做来吸烟,但您需要将Registry引用设为静态变量。导出远程对象时RMI启动一个线程,该远程对象将阻止JVM退出,直到您取消导出它。当远程对象被垃圾收集时,自动导出会自动发生,静态引用会阻止它。

  

Connection拒绝主持人:ruso.89.x.ignorelist.com

这可能意味着您的内部防火墙不允许您向外连接到该主机,即使它是您自己的。或者ruso.89.x.ignorelist.com在您的网络中有一个不同的,不正确的DNS映射。