I need som help with my run() method. How should I accept and register the connections from the clients? I want to both read from the and write to them. How can I detect if the client “hang up” on me (now the server crashes when the client does)?
One more thing, how to unbind a socket if I want to reuse the same port later (i.e. rebooting the server)?
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;
public class ServerController implements Runnable
{
// Network fields.
private static final int DEFAULT_PORT = 1337;
private ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
private Charset ascii = Charset.forName("us-ascii");
private CharsetEncoder asciiEncoder = ascii.newEncoder();
private Selector selector;
private ServerSocketChannel ssChannel;
private void start()
{
try
{
selector = Selector.open();
ssChannel = ServerSocketChannel.open();
ssChannel.configureBlocking(false);
ssChannel.socket().bind(new InetSocketAddress(DEFAULT_PORT));
ssChannel.register(selector, SelectionKey.OP_ACCEPT);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void run()
{
while (running)
{
try
{
selector.select();
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext())
{
SelectionKey sk = (SelectionKey) it.next();
it.remove();
if (sk.isAcceptable())
{
ServerSocketChannel acceptChannel = (ServerSocketChannel) sk.channel();
SocketChannel sChannel = acceptChannel.accept();
sChannel.register(selector, SelectionKey.OP_READ);
}
else if (sk.isReadable())
{
SocketChannel sChannel = (SocketChannel) sk.channel();
if (sChannel.read(buffer) == -1)
{
sk.cancel();
}
}
}
Thread.sleep(1000);
}
catch (InterruptedException e)
{
System.err.println("Server interrupted during sleep.");
System.exit(-1);
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
public static void main(String[] args)
{
new ServerController();
}
}
Thanks!
- Johan