简体   繁体   中英

How to correctly stop serverSocket.accept()

I am writing a simple client/server chat program. The server handles multiple clients in this way:

public void start(int port)
{
    (new Thread(new Runnable()
    {
        @Override
        public void run() {
            try{
                serverSocket = new ServerSocket(port);
                SocketHandler handler;
                while(true)
                {
                    handler = new SocketHandler(serverSocket.accept());
                    handlersList.add(handler);
                    (new Thread(new SocketHandler(socket))).start();
                }
            }catch(IOException e)
            {
                for(SocketHandler handler:handlersList)
                    handler.close();
            }
        }
    })).start();
}

public void stop() throws IOException
{
    serverSocket.close();
}

Basically start() instantiates the ServerSocket and waits for clients to connect indefinitely. Whenever the user wants to close the server, the Server Socket is closed, which causes the accept() to fail and to throw and exception. Then the catch(){} closes the various sockets created. My questions are:

  1. Do I have to close every socket created through serverSocket.accept()?

  2. Is this the right way to stop such a server? That while(true) + use of exceptions for non-exceptional circumstances feels so wrong to me. Is there a better way?

  3. Could I use an ExecutorService and then just call shutdownNow on it? Will the shutdownNow be able to stop the accept() call? Because the api doc states that it is not guaranteed to succeed.

Please, feel free to point out any error/poor design choice that I've made. Ty

You can either close you connections manually (both client/server side) using the close() method or you can set a timeout .

Set a timeout on blocking Socket operations:

ServerSocket.accept();
SocketInputStream.read();
DatagramSocket.receive();

The option must be set prior to entering a blocking operation to take effect. If the timeout expires and the operation would continue to block, java.io.InterruptedIOException is raised. The Socket is not closed in this case.


Is this the right way to stop such a server?

As you say it is a server that means you should not need to stop it but in exceptional conditions.


As you state the shutdownNow() API says:

There are no guarantees beyond best-effort attempts to stop processing actively executing tasks.

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