Skip to content

Instantly share code, notes, and snippets.

@Mistat
Created March 29, 2010 07:13
Show Gist options
  • Save Mistat/347543 to your computer and use it in GitHub Desktop.
Save Mistat/347543 to your computer and use it in GitHub Desktop.
/**
* One Class EchoBackServer
* using non-bloking nio
*/
package mistat;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
*
* @author mistat
*/
public class EchoBackServer {
interface Handler {
void handle(SelectionKey key) throws ClosedChannelException, IOException;
}
public static void main(String ...args) throws Exception {
final ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().setReuseAddress(true);
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
serverSocketChannel.configureBlocking(false);
final Selector seletor = Selector.open();
serverSocketChannel.register(seletor, SelectionKey.OP_ACCEPT, new Handler() {
@Override
public void handle(final SelectionKey key) throws ClosedChannelException, IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel)key.channel();
SocketChannel socketChannel = serverChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(key.selector(), SelectionKey.OP_READ, new Handler() {
final List<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
@Override
public void handle(SelectionKey key) throws ClosedChannelException, IOException {
final SocketChannel socketChannel = (SocketChannel)key.channel();
if (key.isReadable()) {
final ByteBuffer buffer = ByteBuffer.allocate(2048);
socketChannel.read(buffer);
buffer.flip();
buffers.add(buffer);
if (key.interestOps() != (SelectionKey.OP_READ | SelectionKey.OP_WRITE)) {
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
}
if (key.isWritable() && key.isValid()) {
if (!buffers.isEmpty()) {
final ByteBuffer buffer = buffers.get(0);
socketChannel.write(buffer);
buffers.remove(0);
} else {
key.interestOps(SelectionKey.OP_READ);
}
}
}
});
}
});
try {
while(seletor.select() > 0) {
final Set<SelectionKey> keys = seletor.selectedKeys();
final Iterator<SelectionKey> it = keys.iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
it.remove();
Handler handler = (Handler) key.attachment();
handler.handle(key);
}
}
} catch(ClosedChannelException ce) {
ce.printStackTrace();
} catch(IOException ie) {
ie.printStackTrace();
} finally {
try {
for (SelectionKey key: seletor.keys()) {
key.channel().close();
}
}catch (IOException ie) {
ie.printStackTrace();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment