How can I interrupt a ServerSocket accept() method?
You can call close()
from another thread, and the accept()
call will throw a SocketException
.
Stopping a ServerSocket accept() loop thread
I would just do
public void stop() {
running = false;
try{
if (server != null) server.close ();
} catch (IOException ignored){
}
}
It doesn't appear you even need the running flag. However I would use it in your server accept code to determine if an Exception is expected or not. i.e. when running == false ignore all exceptions.
I would make running
volatile.
I would make start()/stop() synchronized if you can run these from different threads.
Java Server Socket Interrupt How to
Here's an example how to close a socket from other thread:
private static volatile ServerSocket serverSocket;
public static void main(String[] args) throws InterruptedException, IOException {
Thread serverThread = new Thread(new ServerThread());
serverThread.start();
Thread.sleep(1000); // wait a bit, then close
serverSocket.close();
}
static class ServerThread implements Runnable {
private BufferedReader input;
public void run() {
try {
serverSocket = new ServerSocket(25);
while (true) {
Socket socket = serverSocket.accept();
// client request handling logic
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
How to interrupt a thread if it is to open socket?
ServerSocket.accept()
is a blocking call that is not responsive to thread interruption. Almost all the java.net
blocking calls (connect, read, accept, etc) do not respond to Thread.interrupt(). This behavior is "as designed".
A way to wake up a thread blocked in .accept()
or .read()
is to close the underlying socket.
Alternatively you could set SO_TIMEOUT (setSoTimeout
) on the ServerSocket, which will cause .accept()
to wake up periodically by throwing a SocketTimeoutException
. You could catch that exception and use it as an opportunity to check the interrupt status on the thread.
The java.nio
package (Java 1.4+) provides an alternate sockets API that is more responsive to interruption.
Java: interrupt accept method without close the server socket
You can set server socket timeout with setSoTimeout.
Once expired a SocketTimeoutException is raised.
Interrupting accept()
The solution here is to not call accept
when there's nothing to do. Just use non-blocking select
or poll
to wait until there's something to accept, then accept
at that point. Unless you create a really tiny timeout there won't be any performance implications of waking up from the non-blocking call and going back to wait on that socket again.
Related Topics
Android: How to Gain Root Access in an Android Application
Can the Android Sdk Work with Jdk 1.7
Countdowntimer in Minutes and Seconds
Firebase Firestore Get Data from Collection
I Would Like to Set My Variables at the Top of My Class Instead of in the Method
Ruby and Duck Typing: Design by Contract Impossible
Jsp, Can It Work Similar to Yield, Layout, Content_For in Ruby/Rails/Erb
How to Click an Element in Selenium Webdriver Using JavaScript
Opening a Shell and Interacting with Its I/O in Java
How to Close Rmiregistry Running on Particular Port
Garbage Collector Log (Loggc) File Rotation with Logrotate Does Not Work Properly
Log4J Does Not Recreate Files on Deletion
Namenode: Java.Net.Bindexception
Why Does My Java Gui "Jump" When Moving It the First Time