this is my first post in stackoverflow, i'm trying to implement a chat using RMI but i'm stuck, i am avoiding the use of rmiregistry, everything was binding well on localhost, but i need it to be accesible from the internet, the ports are forwarded, the firewall down, and actually i can retrieve through the internet an object, i've achived this using

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

So then my NameServer.java binds to that IP, but i lose all access through localhost, now let me explain this. This is the code for 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);
    }
  }
}

This is my policy file:

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";
};

Then I need the ChatServer.java to run, this takes ns and binds himself to it, so the ChatServer can be found, the problem is when i use it from outside my LAN I can get the server running! but when i use localhost i got an exception

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);
    }

So when the ServerChat is registered now any user can execute ChatClient.java to retrieve from the NameService the name of the ChatServer and then connect, but didn't got even there yet because i can't manage to the ChatServer to work. My first though was that when seting the hostname property the localhost get's blocked but nowhere is mentioned, afterwards i've though it may be a problem with the router NAT, could it be?

Exception:

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

Client and server policy files are identical. Used WireShark to see what is happening, a SYN is send and a ACK,RST is recieved. I've burnt all my ideas, any suggestions?

有帮助吗?

解决方案

i've achived this using

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

So then my NameServer.java binds to that IP

No it doesn't. It's a common misperception, but incorrect. RMI always binds its ServerSockets to 0.0.0.0 unless you provide an RMIServerSocketFactory that does otherwise. The effect of java.rmi.server.hostname is to embed its value into the stub (essentially instead of the value returned by InetAddress.getLocalHost()).

   while(true){}

You don't need to smoke your CPU by doing that, but you do need to make the Registry reference a static variable. RMI starts a thread when you export a remote object that will prevent the JVM from exiting until you unexport it. Unexporting happens automatically when the remote object is garbage-collected, and the static reference will prevent that.

Connection refused to host: ruso.89.x.ignorelist.com

That may mean that your internal firewall won't let you connect outwards to that host even though it's your own. Or that ruso.89.x.ignorelist.com has a different, incorrect DNS mapping inside your network.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top