Netty学习之I/O 模型和Java NIO 编程

网站建设5年前发布
53 0 0

1)Java 共支持 3 种网络编程模型/IO 模式: BIO、 NIO、 AIO,2)Java BIO : 同步并阻塞(传统阻塞型), 服务器实现模式为一个连接一个线程, 即客户端有连接请求时服务器端就需要启动一个线程进行处理, 如果这个连接不做任何事情会造成不必要的线程开销,3)Java NIO : 同步非阻塞, 服务器实现模式为一个线程处理多个请求(连接), 即客户端发送的连接请求都会注册到多路复用器上, 多路复用器轮询到连接有 I/O 请求就进行处理。,4)Java AIO(NIO.2) : 异步非阻塞, AIO 引入异步通道的概念, 采用了 Proactor 模式, 简化了程序编写, 有效的请求才启动线程, 它的特点是先由操作系统完成后才通知服务端程序启动线程去处理, 一般适用于连接数较多且连接时间较长的应用。,1)BIO 方式适用于连接数目比较小且固定的架构, 这种方式对服务器资源要求比较高, 并发局限于应用中, JDK1.4以前的唯一选择, 但程序简单易理解。,2)NIO 方式适用于连接数目多且连接比较短(轻操作) 的架构, 比如聊天服务器, 弹幕系统, 服务器间通讯等。编程比较复杂, JDK1.4 开始支持。,3.3.1 Selector 、 Channel 和 Buffer 的关系图,20230306154208d5a8c47955989e3fcb2748d09fd2b909f2700c326,输出流, 不能双向, 但是 NIO 的 Buffer 是可以读也可以写, 需要 flip 方法切换,channel 是双向的, 可以返回底层操作系统的情况, 比如 Linux , 底层的操作系统,通道就是双向的,缓冲区(Buffer) : 缓冲区本质上是一个可以读写数据的内存块, 可以理解成是一个容器对象(含数组), 该对象提供了一组方法, 可以更轻松地使用内存块,缓冲区对象内置了一些机制, 能够跟踪和记录缓冲区的状态变化情况。 Channel 提供从文件、 网络读取数据的渠道, 但是读取或写入的数据都必须经由 Buffer, 如图:,2023030615420959a366487ae4d5da9d2839d400095d903820cd914,20230306154210f4fc88534004a478271261431e116f3ceabf2e281,2)Buffer 类相关方法一览,2023030615421255382de826deac2f776200510646436fcd8d57935,3.4.3 ByteBuffer,20230306154213263b7f58783bd39d76a3818bfc48ec2be99635987,基本介绍, 通道可以同时进行读写, 而流只能读或者只能写, 通道可以实现异步读写数据, 通道可以从缓冲读数据, 也可以写数据到缓冲:,20230307014611523f5433903fa10433e267242d26ab9698b017962,public static Selector open():得到一个选择器对象,public int select(long timeout):监控所有注册的通道,当其中IO操作可以进行时,将对应的SelectionKey加入到内部集合中返回,参数为超时时间,public Set<SlectionKey> selectedKeys():从内部集合中得到所有的SlectionKey,selector.select() //阻塞,selector.select(1000) //阻塞1000s,selector.wakeup(); //唤醒 selector,selector.selectNow(); //不阻塞, 立马返还,NIO 非阻塞 网络编程相关的(Selector、 SelectionKey、 ServerScoketChannel 和 SocketChannel) 关系梳理图,20230306154215c7cb0ee41649ff5b77a425686b9e9de0ef7c29673,SelectionKey, 表示 Selector 和网络通道的注册关系, 共四种:,int OP_ACCEPT: 有新的网络连接可以 accept, 值为 16,int OP_CONNECT: 代表连接已经建立, 值为 8,int OP_READ: 代表读操作, 值为 1,int OP_WRITE: 代表写操作, 值为 4,20230306154216228936f9470134ad86b631458f5a67b41e876b617,ServerSocketChannel 在服务器端监听新的客户端 Socket 连接,20230306154216b5f94a864a75eef552e002bd727489a49ec138514,SocketChannel,网络 IO 通道,具体负责进行读写操作。NIO 把缓冲区的数据写入通道, 或者把通道里的数据读到缓冲区。,20230306154218f178a9a9877506fd026371569628e6ca1b015f501,2023030615421804f5aea35391ee902c3038252b0c245e92d9c8317,DMA: direct memory access 直接内存拷贝(不使用 CPU),2023030615422045c326d1768aced6351143c6e2fc38560f08a5922,20230306154221b425b5a66722dde477d02167bf820d8812dfc2785,系统调用:需要进行线程上下文切换,但不是进程上下文切换,Linux 在 2.4 版本中, 做了一些修改, 避免了从内核缓冲区拷贝到 Socket buffer 的操作, 直接拷贝到协议栈,从而再一次减少了数据拷贝。,20230306154222d877e5e130aea809a02058f570f9801531ccc4951,这里还是有一次少量数据的CPU拷贝,kernel buffer → socket buffer,拷贝的信息很少,比如length,offset等,消耗很低,可以忽略。

© 版权声明

相关文章