package com.github.zangxiaoqiang.io.nio; import java.io.IOException; import java.net.SocketAddress; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; public class NioTcpServer implements SelectorListener { static final Logger LOG = LoggerFactory.getLogger(NioTcpServer.class); Selector selector; // // the key used for selecting accept event // private SelectionKey acceptKey = null; // the server socket for accepting clients private ServerSocketChannel serverChannel = null; //SelectorLoop selectorLoop; private final SelectorLoop acceptSelectorLoop; private final SelectorLoopPool readWriteSelectorPool; private SocketAddress address; public NioTcpServer(SocketAddress add){ acceptSelectorLoop = new NioSelectorLoop("Server-accept"); address = add; readWriteSelectorPool = new FixedSelectorLoopPool("Server-rw", 1); } public void bind(SocketAddress address) { try { serverChannel = ServerSocketChannel.open(); // serverChannel.socket().setReuseAddress(isReuseAddress()); // FIXME What reuse address serverChannel.socket().setReuseAddress(true); serverChannel.socket().bind(address); serverChannel.configureBlocking(false); acceptSelectorLoop.register(true, false, false, false, this, serverChannel, null); } catch (IOException e) { e.printStackTrace(); } } public void ready(boolean accept, boolean connect, boolean read, ByteBuffer readBuffer, boolean write, SelectionKey key) { if (accept) { LOG.debug("acceptable new client"); // accepted connection try { LOG.debug("new client accepted"); createSession(serverChannel.accept()); } catch (final IOException e) { LOG.error("error while accepting new client", e); } } if (read || write) { throw new IllegalStateException("should not receive read or write events"); } } private void createSession(SocketChannel clientChannel) throws IOException { //SocketChannel socketChannel = clientSocket; SelectorLoop readWriteSelectorLoop = readWriteSelectorPool.getSelectorLoop(); clientChannel.configureBlocking(false); final NioTcpSession session = new NioTcpSession(this, clientChannel, readWriteSelectorLoop); session.registeredMessageHandler(msgHandler); readWriteSelectorLoop.register(false, false, true, false, session, clientChannel, cb); } MessageHandler msgHandler = null; public void registMessageHandler(MessageHandler callBack){ msgHandler = callBack; } RegistrationCallback cb = null; public void registCallback(RegistrationCallback callBack){ cb = callBack; } public void start() { bind(address); } }