我知道这个问题已经被问过好几次了,但我还没有找到适合我的答案。基本上我已经用 RMI 实现了一个客户端/服务器解决方案。我唯一的问题是与服务器的连接有时非常慢。
当服务器启动并且客户端第一次连接时,它需要几秒钟才能连接(有时它甚至不连接而是得到 ConnectException),之后我会在尝试与服务器。更令人难以置信的是,当我断开第一个失败的客户端并再次连接时,它工作得非常好。然后客户端在一秒钟内连接,所有通信都完美无缺。
我已经尝试手动启动 rmiregistry,我已经仔细检查了我的 PATH。我无法使用 telnet 连接到该端口,但是当我在该端口上玩我的 Othello 游戏(未使用 RMI)时它可以工作。值得一提的是,我在同一网络和计算机上执行此操作,因此我使用的是 localhost。
TL;DR:当我第一次连接到服务器时,它需要很长时间,但我能够连接。然后当我尝试与它崩溃的方法通信时,我收到“java.rmi.ConnectException:连接拒绝主机:192.xxx.xxx.x;嵌套异常是:java.net.ConnectException:连接超时:连接”。如果我然后关闭该客户端并尝试与另一个客户端连接,则连接大约需要一秒钟,然后一切正常。这是为什么?
客户端代码:
public class NetworkClient {
private Registry registry;
private IArenaServer server;
public NetworkClient(String ipAddress, int port) throws RemoteException {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
registry = LocateRegistry.getRegistry(ipAddress, port);
server = (IArenaServer)(registry.lookup("arenaServer"));
System.out.println("Client successfully connected to server at " + ipAddress + ":" + "port");
} catch (NotBoundException ex) {
Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
} catch (AccessException ex) {
Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
服务器代码:
public class ArenaServer extends UnicastRemoteObject implements IArenaServer {
private int port = 9029;
private String ipAddress;
private Registry registry;
public ArenaServer() throws RemoteException {
if(System.getSecurityManager() == null){
System.setSecurityManager(new RMISecurityManager());
}
// try {
//ipAddress = (InetAddress.getLocalHost()).toString();
registry = LocateRegistry.createRegistry(port);
registry.rebind("arenaServer", this);
System.out.println("Server successfully started...");
//System.out.println("Server's IP address is: " + ipAddress);
// } catch (UnknownHostException ex) {
// ErrorHandler.getInstance().reportError("Cannot get IP address", "");
// }
}
第一次连接后尝试与服务器通信时得到的一般示例:
java.rmi.ConnectException: Connection refused to host: 192.xxx.xxx.x; 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 $Proxy0.getInstalledGames(Unknown Source)
....