Java RMI 无法从外部客户端连接到主机
我在这个项目中使用 RMI 一段时间了。当通过 LAN 运行客户端程序时,我已经让客户端程序连接(除其他外)到服务器,但是当通过 Internet 运行它时,我遇到了以下异常:
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
此错误让人想起我早期实施的 RMI如果我在本地运行客户端而不运行服务器程序,我可以获得逐字错误。对我来说,连接超时意味着服务器响应出现问题。
这是客户端启动:
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();
}
}
有趣的是,这里没有抛出远程异常。 这是服务器启动:
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();
}
}
使用 catch(Exception e) 的不良做法我知道,但请耐心等待。
到目前为止,我知道它在 LAN 上运行良好,这是在 WAN 上发生异常的地方,也是调用服务器中方法的第一个地方:
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();
}
}
}
这是放置在启动器上作为 ping 测试的标签。 gameserver 中的方法 ping() 不执行任何操作,因为 in 是 null 方法。
还值得注意的是,端口 1099 和 7099 被转发到服务器计算机(从堆栈跟踪中应该很明显)。
有人能看到我遗漏/做错的事情吗?如果您需要更多信息,请询问。
编辑:我几乎确定该问题与我的路由器设置无关。当禁用端口转发设置时,我得到一个略有不同的错误:
Client exception: java.rmi.ConnectException: Connection refused to host: (-WAN IP NOT LOCAL IP-);
但它同时出现在本地连接到服务器的计算机和远程计算机上。
此外,当直接通过调制解调器连接服务器时,我让它无缝工作(切断路由器。我只能断定问题出在我的路由器设置中,但看不到哪里(我已经检查并仔细检查了端口)这是我能想到的唯一答案。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您是否使用 NAT(网络地址转换)?如果您的 LAN 在路由器后面使用不可路由的地址(例如 10.x 或 192.169.x 等),则这是典型情况。
如果是这种情况,您需要使用以下选项指定服务器的公共 IP,
Are you using NAT (Network Address Translation)? This is the typical case if your LAN uses non-routable address behind a router (like 10.x or 192.169.x etc).
If this is the case, you need to specify the public IP of the server with following option,