• netty


    nio基础

    nio含义 non-blocking io 非阻塞IO

    三大组件

    channel & buffer

    channel 数据双向通道
    buffer 数据缓冲区

    常见四种channel
    1、FileChannel 文件数据传输通道
    2、DatagramChannel 用于UDP的传输通道
    3、SocketChannel 用于TCP 服务端客户端都可用
    4、ServerSocketChannel 用于TCP 服务端专用

    buffer
    1、ByteBuffer(最常用)
    1.1 MappedByteBuffer
    1.2 DirectByteBuffer
    1.3 HeapByteBuffer
    2、ShortBuffer
    3、IntBuffer
    4、LongBuffer
    5、FloatBuffer
    6、DoubleBuffer
    7、CharBuffer

    Selector

    背景:
    1、多线程是提高效率方法,但是过多的话 CPU跟不上。内存占用高、线程上下文切换成本高、只适合连接数少的场景(一个网络连接看成一个线程)。
    2、使用线程池的话可以通过限制线程数的方法改进1的问题。
    3、但是使用线程池的话,在其阻塞模式下,线程仅能处理一个socket连接,导致线程利用率不高,仅适合短连接场景。

    selector版的设计
    为每个线程提供一个selector,selector监视了多个channel,selecot管理了多个channel,获取这些channel上发生的事件,channel工作在非阻塞模式下(与线程池最大的区别),不会让线程吊死在一个channel上,适合连接数特别多,但流量低的场景。
    事件:可连接、可读、可写

    ByteBuffer

    main(){
    	//输入输出流
    	try(FileChannel channel = new FileInputStream("data.txt").getChannel()){
    		//准备缓冲区
    		ByteBuffer buffer = ByteBuffer.allocate(10);
    		//从channel读取数据,想buffer写入
    		channel.read(buffer);
    		//切换到读模式
    		buffer.flip();
    		while(buffer.hasRemaining()){//是否还有剩余未读数据
    			byte b = buffer.get();//get(i)不会让position往后移,但get()会
    			System.out.println((char) b);
    		}
    	}catch(IOException e){
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    上面代码只能取到10个字符,这里是为了模拟读取多次数据故意这么写的,应为实际场景中allocate的缓冲区不可能分配无限大。
    下面代码为循环使用缓冲

    main(){
    	//输入输出流
    	try(FileChannel channel = new FileInputStream("data.txt").getChannel()){
    		//准备缓冲区
    		ByteBuffer buffer = ByteBuffer.allocate(10);
    		while(true){
    			//从channel读取数据,想buffer写入
    			int len = channel.read(buffer);
    			if(len == -1){//没有内容了
    				break;
    			}
    			//切换到读模式
    			buffer.flip();
    			while(buffer.hasRemaining()){//是否还有剩余未读数据
    				byte b = buffer.get();
    				System.out.println((char) b);
    			}
    			buffer.clear();//切换为写模式
    		}
    	}catch(IOException e){
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    ByteBuffer 结构

    在这里插入图片描述

    属性:
    1、capacity 容量
    2、position 位置(读到那个位置指针)
    3、limit (写入限制,只允许写到哪个位置)
    在这里插入图片描述
    写模式下,向buffer写入数据其中limit等于caoacity
    在这里插入图片描述
    buffer.flip()后 切换为读模式,limit等于写入的最后一个字节的位置可限制只读到有写入数据的位置
    在这里插入图片描述
    clear后切换为写模式
    在这里插入图片描述
    compact方式切换为写模式,用于数据没读完的情况下,保留未读的数据,删除已读数据,且把未读数据往前移
    在这里插入图片描述
    如果没有调用buffer.flip()则从buffer无法读取数据

    使用buffer.compact()切换到写模式会使未读数据前移,建前面已读的位置填满后面的,且写的位置会到前移的上次未读完数据的后一个字节

    ByteBuffer的常见方法

    1、ByteBuffer.allocate(16) java堆内存,读写效率较低,收到垃圾回收的影响
    2、ByteBuffer.allocateDirect(16) 直接内存,读写效率较高(因为会少一次数据拷贝),使用的是系统内存,不会收到垃圾回收的影响。缺点:因为使用的系统内存,所以内存分配比较慢,需要调用操作系统函数

    向buffer写入数据
    int readBytes = channel.read(buf); // 从channel读,向buffer写
    和
    buf.put((byte)127);
    
    • 1
    • 2
    • 3
    从buffer读取数据
    int writeByte = channel.write(buf); //从buffer读,向channel写byte b = buf.get();
    
    • 1
    • 2
    • 3

    get方法会让position读指针向后走,如果想重复读取数据
    可以调用rewind方法将position重新置为0
    或者调用get(int i)方法获取索引 i 的内容,它不会移动读指针

    文件编程

    FileChannel只能工作在阻塞模式下

    获取

    不能直接打开FileChannel,必须通过FileInputStream、FileOutputStream或者RandomAccessFile来获取FileChannel,它们都有getChannel方法。
    通过FileInputStream获取的channel只能读
    通过FileOutputStream获取的channel只能写
    通过RandomAccessFile是否能读写根据构造RandomAccessFile时的读写模式决定

    读取

    在这里插入图片描述

    写入

    在这里插入图片描述

    关闭

    在这里插入图片描述

    位置

    在这里插入图片描述

    两个Channel传输数据

    重要
    transferTo函数:将from内容传到to里面
    这个函数效率高,底层会利用操作系统的零拷贝进行优化
    在这里插入图片描述

  • 相关阅读:
    使用Vue + vue-i18n搭建国际化网站
    10.(vue3.x+vite)组件间通信方式之props与$emit
    分布式协同AI基准测试项目Ianvs:工业场景提升5倍研发效率
    Mac M系列芯片如何重新安装系统
    frp使用oidc认证和搭建
    云计算要学习哪些技术?
    Flask数据库之SQLAlchemy--介绍--链接数据库
    1. 分库分表-1 MySQL 架构
    Oracle数据库连接之TNS-12541异常
    社群运营有哪些好用提高效率的工具呢?
  • 原文地址:https://blog.csdn.net/qq_39103818/article/details/126003687