Martin
Martin

Reputation: 157

Listening on multiple sockets (InputStreamReader)

I'm having a problem with a little game I'm designing in my class. The problem is that I got two clients connected to a server. (client1 and client2) They are each running a game, which in the end, closes the window. As the game window is a JDialog, it will then, when it's closed, send a message, through a socket, to the server, telling it that it's done. I want the server to know which of the two clients were completed first. They are reporting through a PrintWriter on the sockets' OutputStream. What I did was this:

    in1 = new BufferedReader(new InputStreamReader(client.getInputStream()));
    in2 = new BufferedReader(new InputStreamReader(client2.getInputStream()));
    try {
        in1.readLine();
    } catch (IOException ex) {
        Logger.getLogger(gameServer.class.getName()).log(Level.SEVERE, null, ex);
    }
    try {
        in2.readLine();
    } catch (IOException ex) {
        Logger.getLogger(gameServer.class.getName()).log(Level.SEVERE, null, ex);
    }

Problem is that it waits for the first input, before it even starts listening on the second. How can I make it listen on both at the same time? Or solve my problem some other way. Thanks!

Upvotes: 1

Views: 3453

Answers (1)

Tobias
Tobias

Reputation: 9380

Server connection should work like this:

Server gameServer = new Server();

ServerSocket server;
try {
    server = new ServerSocket(10100);
    // .. server setting should be done here
} catch (IOException e) {
    System.out.println("Could not start server!");
    return ;
}

while (true) {
    Socket client = null;
    try {
        client = server.accept();
        gameServer.handleConnection(client);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

In hanleConnection() you start a new thread and run the communication for this client in the created thread. Then the server can accept a new connection (in the old thread).

public class Server {
    private ExecutorService executor = Executors.newCachedThreadPool();

    public void handleConnection(Socket client) throws IOException {    
        PlayerConnection newPlayer = new PlayerConnection(this, client);
        this.executor.execute(newPlayer);
    }

    // add methods to handle requests from PlayerConnection
}

The PlayerConnection class:

public class PlayerConnection implements Runnable {

    private Server parent;

    private Socket socket;
    private DataOutputStream out;
    private DataInputStream in;

    protected PlayerConnection(Server parent, Socket socket) throws IOException {
        try {
            socket.setSoTimeout(0);
            socket.setKeepAlive(true);
        } catch (SocketException e) {}

        this.parent = parent;
        this.socket = socket;

        this.out    = new DataOutputStream(socket.getOutputStream());;
        this.in     = new DataInputStream(socket.getInputStream());
    }

    @Override
    public void run() {                 
        while(!this.socket.isClosed()) {                        
            try {
                int nextEvent = this.in.readInt();

                switch (nextEvent) {
                    // handle event and inform Server
                }
            } catch (IOException e) {}
        }

        try {
            this.closeConnection();
        } catch (IOException e) {}
    }
}

Upvotes: 7

Related Questions