NIO入门

IO和NIO的区别:

  1. IO:通过流处理数据,仅支持阻塞IO。
    核心组件:**InputStream /OutputStream用于字节的读写,Reader / Writer:用于字符流的读写。**读取过程中无法被中断,是阻塞式IO。

  2. NIO:通过管道处理数据,支持阻塞IO和非阻塞IO。

    核心组件:**Channel通道、Buffer缓冲区、Selector选择器。**Channel与Buffer做直接交互,用于数据的传输,支持非阻塞IO,Buffer用于存放数据,Selector用于管理多个管道,允许单个线程处理多个IO。


Channel与Buffer联调

阻塞IO案例

ServerSocketChannel.accept():该方法用于等待客户端连接,直到有客户端连接才会返回,如果没有客户端连接则会一直阻塞。

SocketChannel.read(ByteBuffer):改方法用于接收客户端的数据,直到有数据才会返回,否则将一直阻塞线程。

java 复制代码
    package com.jiawa.netty.server;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.List;
    
    import static com.jiawa.netty.utils.ByteBufferUtil.debugAll;
    
    public class Server {
        private static final Logger logger = LoggerFactory.getLogger(Server.class);
    
        public static void main(String[] args) throws IOException {
            //创建缓存、缓存客户端信息
            ByteBuffer buffer = ByteBuffer.allocate(16);
    
            //创建服务器
            ServerSocketChannel server = ServerSocketChannel.open();
    
    
            //绑定端口
            server.bind(new InetSocketAddress(8080));
    
            //创建客户端存储集合
            List<SocketChannel> clients = new java.util.ArrayList<>();
    
            //接收客户端
            while (true) {
                //阻塞线程,直到有客户端请求连接后释放
                SocketChannel client = server.accept();
    
                //如果有客户端请求,则返回客户端信息
                logger.info("收到客户端请求:{}", client);
                clients.add(client);
    
                for (SocketChannel c : clients) {
                    //读取客户端数据
                    int read = c.read(buffer);
                    if (read > 0) {
                        logger.info("读取客户端数据:{}", read);
                        //打开读
                        buffer.flip();
                        //打印数据
                        debugAll(buffer);
                        //清空
                        buffer.clear();
                    }
    
                }
            }
        }
    }

非阻塞IO案例

server.configureBlocking(false):将 ServerSocketChannel 设置为非阻塞模式。

client.configureBlocking(false):将每个 SocketChannel 设置为非阻塞模式。

设置为非阻塞之后,则不会阻塞线程,不管是否有客户端连接或者接收客户端数据,都会直接返回,不会阻塞线程。

java 复制代码
package com.jiawa.netty.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.List;

import static com.jiawa.netty.utils.ByteBufferUtil.debugAll;

public class Server {
    private static final Logger logger = LoggerFactory.getLogger(Server.class);

    public static void main(String[] args) throws IOException {
        //创建缓存、缓存客户端信息
        ByteBuffer buffer = ByteBuffer.allocate(16);

        //创建服务器
        ServerSocketChannel server = ServerSocketChannel.open();

        //非阻塞
        if (server!= null){
            server.configureBlocking(false);
        }

        //绑定端口
        server.bind(new InetSocketAddress(8080));

        //创建客户端存储集合
        List<SocketChannel> clients = new java.util.ArrayList<>();

        //接收客户端
        while (true) {
            //阻塞线程,直到有客户端请求连接后释放
            SocketChannel client = server.accept();

            //将客户端设置为非阻塞
            if (client != null) {
                client.configureBlocking(false);
            }

            //如果有客户端请求,则返回客户端信息
            if (client != null) {
                logger.info("收到客户端请求:{}", client);
                clients.add(client);
            }


            for (SocketChannel c : clients) {
                //读取客户端数据
                int read = c.read(buffer);
                if (read > 0){
                    logger.info("读取客户端数据:{}", read);
                    //打开读
                    buffer.flip();
                    //打印数据
                    debugAll(buffer);
                    //清空
                    buffer.clear();
                }

            }
        }
    }
}
相关推荐
自由随风飘29 分钟前
python 题目练习1~5
开发语言·python
cynicme1 小时前
力扣3318——计算子数组的 x-sum I(偷懒版)
java·算法·leetcode
Bony-1 小时前
Go语言完全学习指南 - 从基础到精通------语言基础篇
服务器·开发语言·golang
青云交2 小时前
Java 大视界 -- Java 大数据在智能教育学习效果评估与教学质量改进实战
java·实时分析·生成式 ai·个性化教学·智能教育·学习效果评估·教学质量改进
崎岖Qiu2 小时前
【设计模式笔记17】:单例模式1-模式分析
java·笔记·单例模式·设计模式
fl1768313 小时前
基于python的天气预报系统设计和可视化数据分析源码+报告
开发语言·python·数据分析
Lei活在当下3 小时前
【现代 Android APP 架构】09. 聊一聊依赖注入在 Android 开发中的应用
java·架构·android jetpack
ACP广源盛139246256733 小时前
(ACP广源盛)GSV6172---MIPI/LVDS 信号转换为 Type-C/DisplayPort 1.4/HDMI 2.0 并集成嵌入式 MCU
c语言·开发语言·单片机·嵌入式硬件·音视频
不穿格子的程序员3 小时前
从零开始刷算法-栈-括号匹配
java·开发语言·
雪域迷影3 小时前
C#中通过get请求获取api.open-meteo.com网站的天气数据
开发语言·http·c#·get