搜尋
首頁Javajava教程Java IO模型與Netty框架的概述

Java IO模型與Netty框架的概述

Apr 22, 2023 pm 02:34 PM
javaionetty

    什么是Netty

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

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

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

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

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

    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框架的概述

    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中文網其他相關文章!

    陳述
    本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
    什麼是Java虛擬機(JVM)?初學者指南什麼是Java虛擬機(JVM)?初學者指南May 10, 2025 am 12:10 AM

    JvMenablesjava的“寫入,runanywhere” bycompilingCodeIntoplatform-獨立bytecode,whatittheninterpretsorpretsorcompilesIntolachine-specificcode.itoptimizesperformizesperformanceWithJitCompilationWithJitCompilation,ManagesMemoryThroughgargargargargarggarbagecollection,and andensuressececerity

    JVM版本會影響什麼?JVM版本會影響什麼?May 10, 2025 am 12:08 AM

    JVM版本對Java程序的影響包括兼容性、性能優化、垃圾回收策略、安全性和語言特性。 1)兼容性:確保代碼和依賴庫在新JVM上運行。 2)性能:新JVM提升垃圾回收和JIT編譯性能。 3)安全性:修復安全漏洞,提升整體安全性。 4)新特性:如Java8的Lambda表達式和Java17的ZGC垃圾收集器,簡化代碼並提升效率。

    了解Java的JVM:平台獨立背後的秘密了解Java的JVM:平台獨立背後的秘密May 10, 2025 am 12:07 AM

    JVM實現Java的“一次編寫,到處運行”通過將Java字節碼轉換為特定於機器的指令。 1.類加載器加載類。 2.運行時數據區存儲數據。 3.執行引擎轉換字節碼。 4.JNI允許與其他語言交互。 5.本地方法庫支持JNI調用。

    解鎖Java的力量:探索其最佳功能解鎖Java的力量:探索其最佳功能May 10, 2025 am 12:05 AM

    java'spowerstemsssfrom:1)平台獨立viabytecodeandjvm,enaplingCross-platformDevelopment; 2)面向對象的程序,促進促進,促進modularityThroughCapsulation,sastalitance,sastalitance和pollemyormormormormormormormormormormormorphism; 3)AutomaticMememoryManagementwithGargarGargarGargarBagagagageCollection,reduccoltection,reduccoltection

    JVM對於每個平台都一樣嗎?JVM對於每個平台都一樣嗎?May 10, 2025 am 12:04 AM

    No,theJVMisnotthesameforeveryplatform.1)TheJVMprovidesalayerofabstractionforrunningJavabytecode,butitsimplementationvariesbyplatform.2)DifferentversionsoftheJVM,likeOracle'sHotSpot,aretailoredforspecificoperatingsystemstooptimizeperformanceandcompati

    Java平台是否獨立,如果如何?Java平台是否獨立,如果如何?May 09, 2025 am 12:11 AM

    Java是平台獨立的,因為其"一次編寫,到處運行"的設計理念,依賴於Java虛擬機(JVM)和字節碼。 1)Java代碼編譯成字節碼,由JVM解釋或即時編譯在本地運行。 2)需要注意庫依賴、性能差異和環境配置。 3)使用標準庫、跨平台測試和版本管理是確保平台獨立性的最佳實踐。

    關於Java平台獨立性的真相:真的那麼簡單嗎?關於Java平台獨立性的真相:真的那麼簡單嗎?May 09, 2025 am 12:10 AM

    Java'splatFormIndenceIsnotsimple; itinvolvesComplexities.1)jvmcompatiblemustbebeeniblemustbeensuredacrossplatforms.2)Nativelibrariesandsystemcallsneedcarefulhandling.3)

    Java平台獨立性:Web應用程序的優勢Java平台獨立性:Web應用程序的優勢May 09, 2025 am 12:08 AM

    Java'splatformindependencebenefitswebapplicationsbyallowingcodetorunonanysystemwithaJVM,simplifyingdeploymentandscaling.Itenables:1)easydeploymentacrossdifferentservers,2)seamlessscalingacrosscloudplatforms,and3)consistentdevelopmenttodeploymentproce

    See all articles

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    Video Face Swap

    Video Face Swap

    使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

    熱門文章

    熱工具

    SAP NetWeaver Server Adapter for Eclipse

    SAP NetWeaver Server Adapter for Eclipse

    將Eclipse與SAP NetWeaver應用伺服器整合。

    記事本++7.3.1

    記事本++7.3.1

    好用且免費的程式碼編輯器

    EditPlus 中文破解版

    EditPlus 中文破解版

    體積小,語法高亮,不支援程式碼提示功能

    MinGW - Minimalist GNU for Windows

    MinGW - Minimalist GNU for Windows

    這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

    ZendStudio 13.5.1 Mac

    ZendStudio 13.5.1 Mac

    強大的PHP整合開發環境