@Slf4j
public class NIOServer {
private InetAddress addr;
private int port;
private Selector selector;
private static int BUFF_SIZE = 1024;
public NIOServer(InetAddress addr, int port) throws IOException {
this.addr = addr;
this.port = port;
startServer();
}
private void startServer() throws IOException {
// 获得selector及通道(socketChannel)
this.selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
// 绑定地址及端口
InetSocketAddress listenAddr = new InetSocketAddress(this.addr, this.port);
serverChannel.socket().bind(listenAddr);
serverChannel.register(this.selector, SelectionKey.OP_ACCEPT);
log.info("NIOServer运行中...按下Ctrl-C停止服务");
while (true) {
log.info("服务器等待新的连接和selector选择…");
this.selector.select();
// 选择key工作
Iterator keys = this.selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = (SelectionKey) keys.next();
// 防止出现重复的key,处理完需及时移除
keys.remove();
//无效直接跳过
if (!key.isValid()) {
continue;
}
if (key.isAcceptable()) {
this.accept(key);
} else if (key.isReadable()) {
this.read(key);
} else if (key.isWritable()) {
this.write(key);
} else if (key.isConnectable()) {
this.connect(key);
}
}
}
}
private void connect(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
if (channel.finishConnect()) {
// 成功
log.info("成功连接了");
} else {
// 失败
log.info("失败连接");
}
}
private void accept(SelectionKey key) throws IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false);
channel.register(this.selector, SelectionKey.OP_READ);
Socket socket = channel.socket();
SocketAddress remoteAddr = socket.getRemoteSocketAddress();
log.info("连接到: "+ remoteAddr);
}
private void read(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(BUFF_SIZE);
int numRead = channel.read(buffer);
if (numRead == -1) {
log.info("关闭客户端连接: " + channel.socket().getRemoteSocketAddress());
channel.close();
return;
}
String msg = new String(buffer.array()).trim();
log.info("得到了: "+msg);
// 回复客户端
String reMsg = msg + " 你好,这是BIOServer给你的回复消息:" + System.currentTimeMillis();
channel.write(ByteBuffer.wrap(reMsg.getBytes()));
}
private void write(SelectionKey key) throws IOException {
ByteBuffer byteBuffer = ByteBuffer.allocate(BUFF_SIZE);
byteBuffer.flip();
SocketChannel clientChannel = (SocketChannel) key.channel();
while (byteBuffer.hasRemaining()) {
clientChannel.write(byteBuffer);
}
byteBuffer.compact();
}
}