课程名称: 解锁网络编程之NIO的前世今生
课程章节:第4章 【应用】NIO网络编程实战、第3章 【熟悉】NIO网络编程详解
课程讲师: 张小喜
课程内容:
// 创建Selector Selector selector = Selector.open(); //将channel注册到selector上,监听读事件 SelectionKey selectionKey = serverChannel.register(selector, SelectionKey.OP_READ); // 阻塞等待channel就绪事件发生 int select = selector.select(); // 获取发生就绪事件的channel集合 Set<SelectionKey> selectionKeys = selector.selectedKeys();
NIO编程实现步骤
第一步:创建Selector
第二步:创建ServerSocketChannel,并绑定监听端口
第三步:将Channel设置为非阻塞模式
第四步:将Channel注册到Socketor上,监听连接事件
第五步:循环调用Selector的select方法,监测就绪情况
第六步:调用selectKeys方法获取就绪channel集合
第七步:判断就绪事件种类,调用业务处理方法
第八步:根据业务需要决定是否再次注册监听事件,重复执行第三步操作
// 创建Selector Selector selector = Selector.open(); // 2. 通过ServerSocketChannel创建channel通道 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 3. 为channel通道绑定监听端口 serverSocketChannel.bind(new InetSocketAddress(8000)); // 4. **设置channel为非阻塞模式** serverSocketChannel.configureBlocking(false); // 5. 将channel注册到selector上,监听连接事件 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("服务器启动成功"); while (true) { // 获取到可用的channel数量 int readyChannel = selector.select(); if (readyChannel == 0) { continue; } // 获取可用channel的集合 Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); // 由于就绪状态的channel都会放到set里,这里获取到之后就可以删除,以防集合一直增加 iterator.remove(); if (key.isAcceptable()) { acceptHandler(serverSocketChannel, selector); } if (key.isReadable()) { readHandler(key, selector); } } }
private void acceptHandler(ServerSocketChannel serverSocketChannel, Selector selector) throws IOException { // 如果要是接入事件,创建socketChannel SocketChannel accept = serverSocketChannel.accept(); // 将socketChannel设置为非阻塞工作模式 accept.configureBlocking(false); // 将channel注册到selector上,监听 可读事件 accept.register(selector, SelectionKey.OP_READ); // 回复客户端提示信息 accept.write(Charset.forName("UTF-8").encode("atention nnn")); } private void readHandler(SelectionKey selectionkey, Selector selector) throws IOException { // 要从 selectionKey 中获取到已经就绪的channel SocketChannel channel = (SocketChannel) selectionkey.channel(); // 创建buffer ByteBuffer allocate = ByteBuffer.allocate(1024); // 循环读取客户端请求信息 String request = ""; while (channel.read(allocate) > 0) { allocate.flip(); request += Charset.forName("UTF-8").decode(allocate); } channel.register(selector, SelectionKey.OP_READ); if (request.length() > 0) { System.out.println(request); } }
课程收获:
本次实战是以聊天室作为场景,熟悉NIO的常用接口,目前看到NIO更节省内存。
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦