为了账号安全,请及时绑定邮箱和手机立即绑定

【九月打卡】第15天 解锁网络编程之NIO的前世今生

标签:
Java

课程名称 解锁网络编程之NIO的前世今生

课程章节:第4章 【应用】NIO网络编程实战、第3章 【熟悉】NIO网络编程详解

课程讲师: 张小喜


课程内容

https://img1.sycdn.imooc.com//6329debc0001f18c09490561.jpg


// 创建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集合
第七步:判断就绪事件种类,调用业务处理方法
第八步:根据业务需要决定是否再次注册监听事件,重复执行第三步操作
https://img1.sycdn.imooc.com//6329de030001f13f07010266.jpg

// 创建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 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消