🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
~~~ package com.youge.nio.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.util.Iterator; import java.util.Set; /** * @author: hcf * @qq: 46914685 * @email: 46914685@qq.com * @date: 2020/11/26 10:46 */ public class NIOServer { public static void main(String[] args) throws IOException { //创建ServerSocketChannel->ServerSocket ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //获取一个Selector对象 Selector selector = Selector.open(); //绑定一个端口6666,在服务器端上监听 serverSocketChannel.socket().bind(new InetSocketAddress(6666)); //设置非阻塞 serverSocketChannel.configureBlocking(false); //把serverSocketChannel注册到selector,关心事件为 OP_ACCEPT serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); //循环等待客户端连接 while (true) { //等待一秒钟,如果没有事件发生就返回 if (selector.select(1000) == 0) {//没有事件发生 System.out.println("服务器等待了1秒中,无连接"); continue; } //如果返回的>0,就获取到相关的selectionKey集合 //1.如果返回>0,表示已经获取到关注的事件 //2.selector.selectedKeys返回关注事件的集合 //通过 selectedKeys反向获取通道 Set<SelectionKey> selectionKeys = selector.selectedKeys(); //遍历Set<SeletctionKey>,使用迭代器遍历 Iterator<SelectionKey> keyIterator = selectionKeys.iterator(); while (keyIterator.hasNext()) { //获取到selectionKey SelectionKey selectionKey = keyIterator.next(); //根据key中对应的通道发生事件做相应处理 if (selectionKey.isAcceptable()) {//如果是OP_ACCEPT,有新的客户端连接 //该客户端生成一个SocketChannel SocketChannel socketChannel = serverSocketChannel.accept(); System.out.println("客户端连接成功,生成了一个socketChannel "+socketChannel.hashCode()); //将socketChannel设置为非阻塞 socketChannel.configureBlocking(false); //将socketChannel注册到selector,关注事件为OP_READ,同时给socketChannel关联一个byteBuffer socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024)); } if (selectionKey.isReadable()) {//发生OP_READ事件 //通过selectionKey反向获取socketChannel SocketChannel channel = (SocketChannel) selectionKey.channel(); //获取到该channel关联的buffer ByteBuffer buffer = (ByteBuffer) selectionKey.attachment(); // channel.read(buffer); System.out.println("from 客户端:"+new String(buffer.array())); } //手动从集合中删除当前selectionKey,防止重复操作,因为是多线程的 keyIterator.remove(); } } } } ~~~