You need sockets. They serve as the end-points to the connection. Although, you can use alternatives to the blocking Socket
and ServerSocket
implementations.
NIO (New IO) uses channels. It allows for non-blocking I/O:
class Server {
public static void main(String[] args) throws Exception {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
while(true) {
SocketChannel sc = ssc.accept();
if(sc != null) {
//handle channel
}
}
}
}
Using a Selector (optional, but recommended)
You could use a Selector
to switch between reading/writing/accepting to allow blocking only when theres nothing to do (to remove excess CPU usage)
class Server {
private static Selector selector;
public static void main(String[] args) throws Exception {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
Selector selector = Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT);
while(true) {
selector.select();
while(selector.iterator().hasNext()) {
SelectionKey key = selector.iterator().next();
if(key.isAcceptable()) {
accept(key);
}
}
}
}
private static void accept(SelectionKey key) throws Exception {
ServerSocketChannel channel = (ServerSocketChannel) key.channel();
SocketChannel sc = channel.accept();
sc.register(selector, OP_READ);
}
}
SelectionKey
supports accepting via isAcceptable()
, reading via isReadable()
and writing via isWritable()
, so you can handle all 3 on the same thread.
This is a basic example of accepting a connection using NIO. I highly suggest looking into it a bit more to get a better understanding of how things work.