My question is: Would I need another thread for this task?
One way of doing is to use a thread for each client connection. Application method runs the server in an infinite loop listening on the port. When a connection is requested, it spawns a new thread to do the servicing and immediately returns to listening.
ServerSocket listener = new ServerSocket(9898);
try {
while (true) {
new Handler(listener.accept(), clientNumber++).start();
}
} finally {
listener.close();
}
A thread to handle requests on a particular socket.
private static class Handler extends Thread {
private Socket socket;
private int clientNumber;
public Handler(Socket socket, int clientNumber) {
this.socket = socket;
this.clientNumber = clientNumber;
}
public void run() {
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while (true) {
String input = in.readLine();
...
}
} catch (IOException e) {
} finally {
try {
socket.close();
} catch (IOException e) {
log("Couldn't close a socket, what's going on?");
}
}
}
}
Is there an alternative e.g. non-blocking mode?
With non-blocking socket channels, server socket has to register with the selector to do certain operations. By default, a server socket channel is a blocking channel. To make it a non-blocking channel, set the following.
channel.configureBlocking(false);
The Non-blocking server program will look like ...
InetAddress hostIPAddress = InetAddress.getByName("localhost");
int port = 19000;
Selector selector = Selector.open();
ServerSocketChannel channel = ServerSocketChannel.open();
channel.configureBlocking(false);
channel.socket().bind(new InetSocketAddress(hostIPAddress, port));
channel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
Set keys = selector.selectedKeys();
...
}
The non-blocking Client program will look like ...
InetAddress serverIPAddress = InetAddress.getByName("localhost");
InetSocketAddress serverAddress = new InetSocketAddress(
serverIPAddress, 19000);
Selector selector = Selector.open();
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(serverAddress);
int operations = SelectionKey.OP_CONNECT | SelectionKey.OP_READ
| SelectionKey.OP_WRITE;
channel.register(selector, operations);
while (true) {
if (selector.select() > 0) {
Set keys = selector.selectedKeys();
...
}
}
channel.close();