Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unblock a thread blocked on ServerSocket.accept()?

Tags:

java

sockets

I have a server thread with this code:

public void run() {
    try {
        ServerSocket server;
        EneaLog.printLog("Server is running.");
        server = new ServerSocket(this.portnumber);

        while (true) {
            new EneaServerConnection(server.accept(), this.project,stopped).start();
            if (stopped) {
                EneaLog.printLog("Server safe-shutdown completed.");
                EneaLog.printLog("Hi!");
                server.close();
                return;
            }
        }
    } catch (IOException ex) {
        Logger.getLogger(EneaServer.class.getName()).log(Level.SEVERE, null, ex);
        project.getExceptionHandler().handler(ex);
    }
}

and a shutdown method like this:

public void shutdown() {
    EneaLog.printLog("Server shutdown NOW!");
    stopped = true;
}

I want that shutdown can unblock thread that are waiting on server.accept() otherwise I must wait for connection before server shutdown.

I can't do server.close() in shutdown() because I must signal to registered client that server is coming down.

Any ideas?

like image 686
Davide Aversa Avatar asked Oct 02 '09 15:10

Davide Aversa


People also ask

What does the ServerSocket method accept () return?

What does the ServerSocket method accept () return? Upon accepting a connection request from a TCP based client, the accept() method called on the server socket returns a socket that is connected to the client. Data can be sent and received using the socket returned by the accept() method.

Does ServerSocket accept block?

The ServerSocketChannel. accept method blocks and returns a SocketChannel object when a connection is accepted. The ServerSocket. read method blocks until input data are available, or a client is disconnected.

Which method can be used for ServerSocket?

The server invokes the accept() method of the ServerSocket class. This method waits until a client connects to the server on the given port. After the server is waiting, a client instantiates a Socket object, specifying the server name and the port number to connect to.

What happens if ServerSocket?

Creates a server socket and binds it to the specified local port number, with the specified backlog. A port number of 0 means that the port number is automatically allocated, typically from an ephemeral port range. This port number can then be retrieved by calling getLocalPort .


2 Answers

I try to design my code so that it can be "shutdown" with an interrupt. Mainly, this is because the Executor framework in Java's concurrency package uses interrupt to cancel running tasks. Also, the "shutdown" task doesn't have to know any internals of the task being killed.

However, a call to accept will not respond to an interrupt unless it is created from a ServerSocketChannel. A server created with a ServerSocket constructor will ignore interrupts, and I haven't found a way to reconfigure this.

If you can't change the code that creates the server, arrange for another thread to call close on the server socket. This will also raise an exception in thread blocked on accept, regardless of the method used to create the server socket.

This turns out to be a really big pain when using SSL. A JSSE socket is not created from an InterruptibleChannel, and won't respond to a simple interrupt on the thread.


I just noticed that the question says that the server can't be closed without notifying the client. Successfully interrupting a socket results in its closure.

On a call to accept this shouldn't be a problem, since the client is not connected if the server socket is blocked in accept. That should only be an issue for Socket instances, that represent current connections.

If that doesn't satisfy the notification requirements, a rework to use NIO's ServerSocketChannel in non-blocking mode may be necessary.

like image 143
erickson Avatar answered Nov 10 '22 23:11

erickson


You should be able to close the socket from another thread.

like image 2
Tom Hawtin - tackline Avatar answered Nov 11 '22 00:11

Tom Hawtin - tackline