import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.util.Iterator;
/**
* Created with IntelliJ IDEA.
*
* @Auther: hengjiuyang
* @Date: 2021/04/09/2:38 下午
* @Description:
*/
public class NIODiscardServer {
private static final Logger logger = LoggerFactory.getLogger(NIODiscardServer.class);
public static void startServer() throws IOException {
//获取选择器
Selector selector = Selector.open();
//获取通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 设为非阻塞
serverSocketChannel.configureBlocking(false);
// 绑定连接
serverSocketChannel.bind(new InetSocketAddress(9047));
logger.info("服务器启动");
//将通道注册到选择器
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
//轮询
while (selector.select() > 0){
//获取选择键集合
Iterator<SelectionKey> selectionKeys = selector.selectedKeys().iterator();
while (selectionKeys.hasNext()){
SelectionKey selectedKey = selectionKeys.next();
//判断key具体是什么事件
if (selectedKey.isAcceptable()){
//若选择键的IO事件是"连接就绪"状态,就获取客户端连接
SocketChannel socketChannel = serverSocketChannel.accept();
//切换非阻塞模式
socketChannel.configureBlocking(false);
//将这个新连接的通道事件注册到选择器上
socketChannel.register(selector,SelectionKey.OP_READ);
}else if (selectedKey.isReadable()){
SocketChannel socketChannel = (SocketChannel) selectedKey.channel();
//读取数据 然后丢弃
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
int length = 0;
//buffer创建默认是写入模式 从通道读取到buffer后
while ((length = socketChannel.read(byteBuffer)) > 0){
//需要flip()一下变成读取模式 才能将buffer中的数据再写入outChannel
byteBuffer.flip();
//第二次切换 clear() 重新变成写入模式
byteBuffer.clear();
}
socketChannel.close();
}
//移除选择键
selectionKeys.remove();
}
}
//关闭连接
serverSocketChannel.close();
}
}