首页 > Java > java教程 > 正文

Java IO模型和Netty框架的概述

PHPz
发布: 2023-04-22 14:34:07
转载
1420人浏览过

    什么是Netty

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

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

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

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

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

    立即学习Java免费学习笔记(深入)”;

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

    Netty典型应用:

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

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

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

    IO模型

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

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

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

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

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

    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

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

    使用 ctrl+]

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

    Maven 使用指南 中文WORD版
    Maven 使用指南 中文WORD版

    本文档主要讲述的是Maven 使用指南;Apache Maven,是一个软件(特别是Java软件)项目管理及自动构建工具,由Apache软件基金会所提供。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看

    Maven 使用指南 中文WORD版 0
    查看详情 Maven 使用指南 中文WORD版

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

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

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

    NIO

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

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

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

    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();
        }
    }
    登录后复制

    图示理解

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

    本地文件读案例

    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

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

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

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

    以上就是Java IO模型和Netty框架的概述的详细内容,更多请关注php中文网其它相关文章!

    java速学教程(入门到精通)
    java速学教程(入门到精通)

    java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

    下载
    来源:亿速云网
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
    最新问题
    开源免费商场系统广告
    热门教程
    更多>
    最新下载
    更多>
    网站特效
    网站源码
    网站素材
    前端模板
    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送
    PHP中文网APP
    随时随地碎片化学习

    Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号