Java RMI cannot connect to host from external client.
- by Koe
I've been using RMI in this project for a while. I've gotten the client program to connect (amongst other things) to the server when running it over my LAN, however when running it over the internet I'm running into the following exception:
java.rmi.ConnectException: Connection refused to host: (private IP of host machine); nested exception is:
java.net.ConnectException: Connection timed out: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy1.ping(Unknown Source)
at client.Launcher$PingLabel.runPing(Launcher.java:366)
at client.Launcher$PingLabel.<init>(Launcher.java:353)
at client.Launcher.setupContentPane(Launcher.java:112)
at client.Launcher.<init>(Launcher.java:99)
at client.Launcher.main(Launcher.java:59)
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown Source)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown Source)
... 12 more
This error is remeniscent of my early implementation of RMI and I can obtain the error verbatum if I run the client locally without the server program running as well. To me Connection Timed Out means a problem with the server's response.
Here's the client initiation:
public static void main(String[] args)
{
try
{
String host = "<WAN IP>";
Registry registry = LocateRegistry.getRegistry(host, 1099);
Login lstub = (Login) registry.lookup("Login Server");
Information istub = (Information) registry.lookup("Game Server");
new Launcher(istub, lstub);
}
catch (RemoteException e)
{
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
catch (NotBoundException e)
{
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
Interestingly enough no Remote Exception is thrown here.
Here's the server initiation:
public static void main(String args[])
{
try
{
GameServer gobj = new GameServer();
Information gstub = (Information) UnicastRemoteObject.exportObject(
gobj, 1099);
Registry registry = LocateRegistry.createRegistry(1099);
registry.bind("Game Server", gstub);
LoginServer lobj = new LoginServer(gobj);
Login lstub = (Login) UnicastRemoteObject.exportObject(lobj, 7099);
// Bind the remote object's stub in the registry
registry.bind("Login Server", lstub);
System.out.println("Server ready");
}
catch (Exception e)
{
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
Bad practice with the catch(Exception e) I know but bear with me.
Up to this stage I know it works fine over the LAN, here's where the exception occurs over the WAN and is the first place a method in the server is called:
private class PingLabel extends JLabel
{
private static final long serialVersionUID = 1L;
public PingLabel()
{
super("");
runPing();
}
public void setText(String text)
{
super.setText("Ping: " + text + "ms");
}
public void runPing()
{
try
{
PingThread pt = new PingThread();
gameServer.ping();
pt.setRecieved(true);
setText("" + pt.getTime());
}
catch (RemoteException e)
{
e.printStackTrace();
}
}
}
That's a label placed on the launcher as a ping test. the method ping(), in gameserver does nothing, as in is a null method.
It's worth noting also that ports 1099 and 7099 are forwarded to the server machine (which should be obvious from the stack trace).
Can anyone see anyting I'm missing/doing wrong? If you need any more information just ask.
EDIT: I'm practically certain the problem has nothing to do with my router settings. When disabling my port forwarding settings I get a slightly different error:
Client exception: java.rmi.ConnectException: Connection refused to host: (-WAN IP NOT LOCAL IP-);
but it appears both on the machine locally connected to the server and on the remote machine.
In addition, I got it to work seamlessly when connecting the server straight tho the modem (cutting out the router. I can only conclude the problem is in my router's settings but can't see where (I've checked and double checked the port forwarding page). That's the only answer i can come up with.