1

我知道这个问题已经被问过好几次了,但我还没有找到适合我的答案。基本上我已经用 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)
....
4

1 回答 1

1

这听起来像是 java.rmi.server.hostname 的一个案例。请参阅 RMI 常见问题解答中的 A.1 项,可通过 RMI 主页访问。

于 2012-12-09T22:26:22.613 回答