简体   繁体   中英

Java RMI server to client communication not working

I'm developing a game which use server communication with socket and RMI. I'm quite new to RMI and i'm encountering some problems while trying to communicate between a server and a client which are not on the same PC. In localhost it work flawlessy, otherwise communication don't work as expected. Here some code snippets:

public RMIServer (ServerInterface mainServer){
    this.mainServer = mainServer;
}

public void startServer() throws IOException {
    Registry registry  = createOrLoadRegistry(Server.RMIPORT);
    try {
        System.out.println("Insert server ip address: ");
        Scanner in = new Scanner(System.in);
        String address = in.nextLine();
        in.close();
        System.setProperty("java.rmi.server.hostname", address);
        registry.bind("RMIServerInterface", this);
        UnicastRemoteObject.exportObject(this, Server.RMIPORT+1);
    } catch (RemoteException | AlreadyBoundException e) {
        System.err.println(e.getMessage());
    }
}    

private Registry createOrLoadRegistry(int port) throws IOException{
    try {
        System.out.println("creating register.. ");
        return LocateRegistry.createRegistry(port);
    } catch (RemoteException e) {
        System.err.println(e.getMessage());
    }
    try {
        return LocateRegistry.getRegistry(port);
    } catch (RemoteException e) {
        System.err.println(e.getMessage());
    }
    return null;
}

Socket works very good instead.

EDIT: To let RMI work in first place I was forced to use:

System.setProperty("java.rmi.server.hostname")

enter code here

because server IP was randomly set to 127.0.1.1 (loopback). I printed the stack track on server side and this was the result:

    creating register.. 
Insert server ip address: 
192.168.1.73
Socket server is ready
Recieved RMI client connection
create first room..
cchvo has been added to room
Number of players: 1
java.rmi.ConnectException: Connection refused to host: 127.0.1.1; nested exception is: 
  java.net.ConnectException: Connessione rifiutata (Connection refused)
  at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
  at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
  at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
  at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:130)
  at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
  at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
  at com.sun.proxy.$Proxy1.notifyNewPlayer(Unknown Source)
  at server.RMIPlayer.notifyNewPlayer(RMIPlayer.java:28)
  at server.Room.notifyNewPlayer(Room.java:147)
  at server.Room.addPlayer(Room.java:106)
  at server.Server.createRoom(Server.java:98)
  at server.Server.addPlayerFirstAvailableRoom(Server.java:119)
  at server.RMIServer.addRoom(RMIServer.java:82)
  at server.RMIServer.loginPlayer(RMIServer.java:75)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346)
  at sun.rmi.transport.Transport$1.run(Transport.java:200)
  at sun.rmi.transport.Transport$1.run(Transport.java:197)
  at java.security.AccessController.doPrivileged(Native Method)
  at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
  at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
  at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
  at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
  at java.security.AccessController.doPrivileged(Native Method)
  at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.ConnectException: Connessione rifiutata (Connection refused)
  at java.net.PlainSocketImpl.socketConnect(Native Method)
  at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
  at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
  at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
  at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
  at java.net.Socket.connect(Socket.java:589)
  at java.net.Socket.connect(Socket.java:538)
  at java.net.Socket.<init>(Socket.java:434)
  at java.net.Socket.<init>(Socket.java:211)
  at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
  at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
  at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
  ... 30 more

You're doing everything in the wrong order.

  1. Set java.rmi.server.hostname .
  2. Export the remote object.
  3. Create the Registry.
  4. Bind the remote object to the Registry.

I've finally managed to fix this by simply adding

System.setProperty ("java.rmi.server.hostname", clientIp)

in client too. Hope to help someone with the same problems.

PS: only one PC (with Debian) over 3 had this problem with hostname, the others running Ubuntu and Windows had not. Thanks for the answers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM