千家信息网

Java的IO模型和Netty框架是什么

发表于:2025-02-21 作者:千家信息网编辑
千家信息网最后更新 2025年02月21日,这篇文章主要介绍"Java的IO模型和Netty框架是什么",在日常操作中,相信很多人在Java的IO模型和Netty框架是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家
千家信息网最后更新 2025年02月21日Java的IO模型和Netty框架是什么

这篇文章主要介绍"Java的IO模型和Netty框架是什么",在日常操作中,相信很多人在Java的IO模型和Netty框架是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Java的IO模型和Netty框架是什么"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    什么是Netty

    • 异步,基于事件驱动的网络应用框架,用以快速开发高性能,高可靠的网络IO程序

    • 主要针对在TCP协议下,面向Clients端的高并发应用

    • 本质是一个NIO框架,适用于服务器通讯等场景

    异步:发送请求无需等待响应,程式接着往下走。

    事件驱动:一个连接事件或者断开事件,或者读事件或者写事件,发生后的后续处理。

    Netty典型应用:

    • 高性能rpc框架用来远程服务(过程)调用,比如Dubbo。

    • 游戏行业,页面数据交互。

    • 大数据领域如Hadoop高性能通讯和序列化组件(AVRO)。

    IO模型

    简单理解就是用什么通道去进行数据发送和接收。

    BIO:一个连接一个线程,连接不做任何事会造成不必要的线程开销。适用于连接数目较小且固定的架构。

    NIO:服务端一个线程(也可以多个),维护一个多路复用器。由多路复用器去处理IO线程。适用于连接数目多且较短的架构

    AIO:异步非阻塞,还未得到广泛应用。适用于连接数目多且连接较长的架构。

    BIO

    BIO编程简单流程

    • 服务端创建启动ServerSocket

    • 客户端启动Socket对服务器进行通信,默认服务器会对每一个客户创建一个线程。

    • 客户端发出请求后,先咨询线程是否有响应,如果没有则等待或者拒绝。

    • 如果有响应,则等待请求结束后,再继续执行。(阻塞)

    BIO简单实例

    public class BIOserver {    public static void main(String[] args) throws IOException {        // 为了方便直接用了Executors创建线程池        ExecutorService service = Executors.newCachedThreadPool();        //指定服务端端口        ServerSocket serverSocket = new ServerSocket(6666);        System.out.println("服务器启动");        while(true){            //阻塞等待连接            Socket socket = serverSocket.accept();            System.out.println("连接到一个客户端");            //每个连接对应一个线程            service.execute(new Runnable() {                @Override                public void run() {                    try {                        handler(socket);                    }catch (Exception e){                        e.printStackTrace();                    }                }            });        }    }    public static void handler(Socket socket) throws IOException {        System.out.println("Thread:"+Thread.currentThread().getId());        byte[] bytes = new byte[1024];        InputStream inputStream = socket.getInputStream();        while (true){            //阻塞等待读取            int n = inputStream.read(bytes);            if(n!=-1){                System.out.println(new String(bytes,0,n));            }else {                break;            }        }        socket.close();    }}

    测试:使用windows的telnet

    使用 ctrl+]

    可以在服务端控制台看到,已经读取到发送的数据

    NIO

    三大核心部分:Channel(可类比Socket),Buffer,Selector

    大概是这个样子。客户端和Buffer交互,Buffer和Channel是一对一的关系。Selector选择操作Channel(事件驱动,如果Channel有事件发生,Selector才去选择操作。)

    Buffer

    Buffer基本使用

    ByteBuffer使用场景较为广泛。

    buffer就是一个内存块,所以说nio是面向块/缓冲,底层是数组。数据读写是通过buffer。可以使用方法flip切换读写。

    public class BufferNio {    public static void main(String[] args) {        //创建buffer容量为5个int        IntBuffer buffer = IntBuffer.allocate(5);        //放数据        buffer.put(1);        buffer.put(2);        buffer.put(3);        buffer.put(4);        buffer.put(5);        //读写切换        buffer.flip();        //取数据        //内部维护一个索引,每次get索引都会往后边移动        while(buffer.hasRemaining()){            System.out.println(buffer.get());        }    }}

    Buffer四个主要属性

    // Invariants: mark <= position <= limit <= capacity    private int mark = -1;    private int position = 0;    private int limit;    private int capacity;

    mark:标记,很少改变

    position:下一个要被读元素的位置,为下次读写做准备

    limit:缓冲器当前的终点,不能对缓冲区极限意外的区域读写,可变。

    capacity:不可变,创建时指定的最大容量。

    上边出现了读写切换的方法flip,我们看下源码,可以看出来通过改变属性实现可读可写的。

    public final Buffer flip() {        limit = position;        position = 0;        mark = -1;        return this;    }

    可以通过啊更改limit或者position来实现你想要的操作。参数自己决定

    buffer.limit(2);        buffer.position(1);

    Channel

    可读可写,上接Selector,下连Buffer。

    当客户端连接ServerSocketChannel时,创建客户端自己的SocketChannel。

    本地文件写案例

    public class ChannelNio {    public static void main(String[] args) throws IOException {        String str = "少壮不努力,老大徒伤悲";        //创建输出流        FileOutputStream os = new FileOutputStream("D:\\xxxxxxxxxxxxxxxxxxx\\a.txt");        //获取FileChannel        FileChannel channel = os.getChannel();        //创建缓冲        ByteBuffer buffer = ByteBuffer.allocate(1024);        //把字符串放入缓冲区        buffer.put(str.getBytes());        //反转ByteBuffer        buffer.flip();        //将ByteBuffer写入到FileChannel        channel.write(buffer);        //关闭流        os.close();    }}

    图示理解

    本地文件读案例

    public class ChannelNio {    public static void main(String[] args) throws IOException {        FileInputStream is = new FileInputStream("D:\\xxxxxxxxxxxxxxxxxxx\\a.txt");        FileChannel channel = is.getChannel();        ByteBuffer buffer = ByteBuffer.allocate(1024);        channel.read(buffer);        System.out.println(new String(buffer.array()));        is.close();    }}

    本地文件拷贝案例

    方法一

    public class ChannelNio {    public static void main(String[] args) throws IOException {        FileInputStream is = new FileInputStream("D:\\xxxxxxxxxxxxxxxxxxx\\a.txt");        FileChannel channel = is.getChannel();        ByteBuffer buffer = ByteBuffer.allocate(1024);        FileOutputStream os = new FileOutputStream("D:\\xxxxxxxxxxxxxxxxxxx\\b.txt");        FileChannel osChannel = os.getChannel();        while (true){            buffer.clear();            int i = channel.read(buffer);            if(i==-1){                break;            }            buffer.flip();            osChannel.write(buffer);        }        is.close();        os.close();    }}

    方法二

    public class ChannelNio {    public static void main(String[] args) throws IOException {        FileInputStream is = new FileInputStream("D:\\xxxxxxxxxxxxxxxxxxx\\HELP.md");        FileChannel channel = is.getChannel();        FileOutputStream os = new FileOutputStream("D:\\xxxxxxxxxxxxxxxxxxx\\HELP222.md");        FileChannel osChannel = os.getChannel();        osChannel.transferFrom(channel,0,channel.size());        is.close();        os.close();    }}

    Selector

    用一个线程处理多个客户端连接。可以检测多个注册通道的事件,并作出相应处理。不用维护所有线程。

    Selector可以获得被注册的SocketChannel的一个SelectionKey集合,然后监听select,获得有事件发生的SelectionKey,最后通过SelectionKey获得通道进行相应操作,完成业务。

    到此,关于"Java的IO模型和Netty框架是什么"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

    事件 线程 服务 客户 框架 客户端 数据 模型 方法 缓冲 服务器 处理 学习 应用 阻塞 于连 多个 数目 文件 架构 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 简述云计算与网络技术的关系 联想服务器进入u盘启动快捷键 天河区质量网络技术开发动态 香港服务器低延迟哪个好亿速云 网络安全法情况报告 央行软件开发商 腾讯云学生1元服务器 研究大数据下网络安全的意义 湖南上容数据库 惠普dl160服务器针脚接线 我的世界手机开服务器没生物 软件log数据库 数据库修改用户名称 网络安全与网络舆情关系 关系型和非关系型数据库的联系 sql强行删除数据库 广州东秀网络技术有限公司 邹平瓷砖软件开发咨询 滨海新区新时代软件开发价钱 市可搜网络技术有限公司 饥荒怎样找到自己的服务器 网络技术应用操作题会考 网络安全靠人民蒙古文字 我的世界斗罗服务器手机版下载 nba数据库统计贴吧 网络安全的泄露 华为erp软件开发 西安云鸟科技互联网公司 深圳市众合联兴互联网科技 三河市启润网络技术有限公司
    0