Search code examples
javanetwork-programmingservermultiplayer

Java server is waiting for client response


I've been into game-developing for a while, and I'm trying to make my next game multi-player. I'm trying to write a server that will loop through every 1/16th of a second or so to calculate the position of all the entities and such in the game. The client will then be able to request all this information when it needs to.

As such, I tried writing a simple server/client that can exchange information. Part of the code can be seen here:

ServerSocket listener;
Socket socket;

while(running)
{
    socket = listener.accept();

    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    out.println("information"); //sending the string "information" to any client that has connected
}

The only issue is that the server waits for the client to connect every time listener.accept() is called, therefore halting everything else in the loop that would need to be done. How can I make it so that many clients can connect/request information without the server stopping to specifically listen for them every single time? I really don't have much of a clue when it comes to all this networking stuff, which is why I'm trying to learn. I've never delved into it, so I apologize if it's a seemingly simple solution.

(hopefully I have the right idea on how games work here? I'd think position and everything is server-side, and the only things handled client-side are rendering and user-input and such.)


Solution

  • You need to switch to NIO, which gives non-blocking capabilities:

    class Server {
        public static void main(String[] args) {
            try {
                ServerSocketChannel serverSocket = ServerSocketChannel.open();
                serverSocket.configureBlocking(false);
                serverSocket.bind(port);
    
                while(running) {
                    SocketChannel channel = serverSocket.accept();
    
                    //...
                }
            }
        }
    }
    

    When serverSocket.accept() is called, it'll return null if there is no connection to accept, instead of blocking.

    You could also use a Selector to manage reading/writing and accepting on a single thread. Keep in mind, you'd need a thread for each user as well to block for reading. Instead, a Selector will notify you of when you need to read from any channel.