Java Non-blocking Sockets
In this page:
Blocking vs Non-blocking Sockets
A classic java.net.Socket blocks the calling thread while waiting for data, requiring one dedicated thread per connection, while NIO's SocketChannel can be switched into non-blocking mode, letting one thread service many connections.
Example: Blocking vs Non-blocking Sockets
import java.nio.channels.SocketChannel;
public class Main {
public static void main(String[] args) throws Exception {
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false); // one thread can service many such channels
System.out.println("Non-blocking: " + !channel.isBlocking());
channel.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Opening a ServerSocketChannel
ServerSocketChannel is the NIO equivalent of ServerSocket, accepting incoming connections but capable of doing so non-blockingly when registered with a Selector.
Example: Opening a ServerSocketChannel
import java.nio.channels.ServerSocketChannel;
public class Main {
public static void main(String[] args) throws Exception {
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(new java.net.InetSocketAddress(0));
server.configureBlocking(false); // can accept non-blockingly when registered with a Selector
System.out.println("Listening on port " + server.socket().getLocalPort());
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Registering Channels with a Selector
A non-blocking channel is registered with a Selector for a specific interest, such as OP_ACCEPT or OP_READ, and the Selector reports back only the channels that are actually ready for that operation.
Example: Registering Channels with a Selector
import java.nio.channels.*;
public class Main {
public static void main(String[] args) throws Exception {
Selector selector = Selector.open();
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(new java.net.InetSocketAddress(0));
server.configureBlocking(false);
server.register(selector, SelectionKey.OP_ACCEPT); // interested in accept events only
System.out.println("Registered for OP_ACCEPT");
selector.close();
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
The Selector Event Loop
A Selector-based server runs a loop calling select(), which blocks until at least one registered channel is ready, then iterates the ready set to handle each event, such as accepting a connection or reading available data.
Example: The Selector Event Loop
import java.nio.channels.*;
public class Main {
public static void main(String[] args) throws Exception {
Selector selector = Selector.open();
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(new java.net.InetSocketAddress(0));
server.configureBlocking(false);
server.register(selector, SelectionKey.OP_ACCEPT);
int ready = selector.selectNow(); // non-blocking check instead of select() for this demo
System.out.println("Ready channels: " + ready);
selector.close();
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Accepting and Reading Client Connections
Inside the event loop, an OP_ACCEPT-ready key means a new client can be accepted, while an OP_READ-ready key means an already-connected client has data waiting to be read into a buffer.
Example: Accepting and Reading Client Connections
import java.nio.channels.*;
import java.net.InetSocketAddress;
public class Main {
public static void main(String[] args) throws Exception {
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(new InetSocketAddress(0));
server.configureBlocking(false);
// OP_ACCEPT-ready key -> server.accept() returns a new client SocketChannel
// OP_READ-ready key -> that client channel has data waiting in a buffer
System.out.println("Server ready to accept on port " + server.socket().getLocalPort());
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 5 topics to unlock
0/5 topics done
Complete these topics first: