美文网首页我爱编程
JAVA的NIO学习笔记第一节-Unix的IO模型

JAVA的NIO学习笔记第一节-Unix的IO模型

作者: 彬荣 | 来源:发表于2018-01-11 16:06 被阅读3次

Unix五种I/O模型

第一种:阻塞式IO,最常用的I/O模型就是阻塞式I/O模型

第二种:非阻塞式IO,recvfrom从应用层到内核的时候,如果该缓冲区没有数据的话,就直接返回一个EWOULDBLOCK错误,一般都对非阻塞I/O模型进行轮询检查这个状态,看内核是不是有数据到来。

第三种:I/O复用模型,Linux提供select/poll,进行通过将一个或多个fd传递给select或poll系统调用,阻塞在select操作上,这样select/poll可以帮助我们侦测多个fd是否处于就绪状态。select/poll是顺序扫描fd是否就绪,而且支持的fd有限,因此它的使用受到了一些制约。Linux还提供了一个epoll系统调用,epoll使用基于事件驱动方式代替顺序扫描,因此性能更高。当有fd就绪时,立即回调函数rollback。

第四种:信号驱动IO,由内核通知我们何时可以开始一个I/O操作。

第五种:异步IO,由内核通知我们I/O操作何时已经完成。

epoll和select模型的区别

1.支持一个进程打开的socket描述符不受限制。select最大的缺陷就是单个进程所打开的FD是有一定限制的,默认为1024。而epoll并没有限制,它所支持的FD上限是操作系统的最大文件句柄数。

2.I/O效率不会随着FD数目的增加而线性下降。select/poll模型的一个致命缺点是当你拥有一个socket集合时,由于网络延迟或者链路空闲,任一时刻只有少部分socket是活跃的,但是select/poll每次调用都会线性扫描全部的集合,导致效率线性下降。epoll不存在这个问题,它只会对活跃的socket进行操作,这是因为内核实现中采用事件驱动的方式,都有一个callback函数,只有活跃的socket才会去主动调用callback函数。

3.epoll使用mmap加速内核与用户空间的消息传递。select模型会将用户消息复制到内核空间,而epoll采用mmap映射内存的方式进行。

4.epoll的API更简单。

java中各种I/O实现方式

第一种 BIO阻塞式IO

BIO的主要问题在于每当有一个新的客户端请求接入时,服务端必须创建一个新的线程处理新接入的客户端链路,一个线程只能处理一个客户端连接。

第二种是伪异步IO

伪异步IO通信框架采用了线程池实现,因此避免了每个请求都创建一个独立线程造成的线程资源耗尽问题。但是由于它底层的通信依然采用同步阻塞模型,因此无法从根本上解决问题。

第三种NIO非阻塞IO

第四种异步IO

TCP粘包/拆包问题

TCP是个“流”协议,所谓流,就是没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。

产生粘包/拆包的原因?

1.应用程序write写入的字节大小大于套接字接口发送缓冲区大小。

2.进行MSS大小的TCP分段。MSS:最大报文段长度MSS选项是TCP协议定义的一个选项,MSS选项用于在TCP连接建立时,收发双方协商通信时每一个报文段所能承载的最大数据长度。

3.以太网帧的payload大于MTU进行IP分片。MTU(Maximum Transmission Unit)最大的传输单元。payload是post数据的大小

解决TCP/IP的拆包和粘包问题的方案?

1.消息定长,例如每个报文的大小为固定长度200字节,如果不够,空位补空格;

2.在包尾增加回车换行符进行分割,例如FTP协议

3.将消息分为消息头和消息体,消息头中包含消息总长度。

4.采用更复杂的应用协议层。

几种常见的解决拆包粘包的方案:

1.LineBasedFreamDecoder+StringDecoder方式。工作原理是依次遍历ByteBuf中的可读字节,判断是否有换行符,如果有,就以此位置为结束位置,从可读索引到结束位置区间的字节就组成了一行。它是以换行符为结束标志的解码器。支持携带结束符或者不携带结束符两种解码方式,同时支持配置单行的最大长度。如果连续读取到最大长度后仍然没有发现换行符,就会抛出异常。

2.DelimiterBasedFrameDecoder可以自定义分隔符。

3.FixedLengthFrameDecoder是固定长度的解码器,它能够按照指定的长度对消息进行自动解码。无论一次接收到多少数据包,它都会按照构造函数中设置的固定长度进行解码,如果是半包消息,会缓存半包消息并等待下个包到达后进行拼包,直到读取到一个完整的包。

相关文章

  • NIO学习笔记

    NIO 操作系统背景知识 unix提供了5中io模型,其中java的底层实现依赖的是操作系统的io复用模型。lin...

  • JAVA的NIO学习笔记第一节-Unix的IO模型

    Unix五种I/O模型 第一种:阻塞式IO,最常用的I/O模型就是阻塞式I/O模型 第二种:非阻塞式IO,recv...

  • note

    Java IO,NIO,NIO2 以及与操作系统,磁盘 IO NIO模型selector NIO的核心是IO线程池...

  • 01-IO模型-BIO、NIO、AIO

    IO模型 在学习netty之前,需要对JAVA的io模型进行一个了解,因为netty就是基于NIO进行封装的,io...

  • 1.Netty基本-io模式,线程模型,Reactor模式都啥呀

    关于IO模式,线程模型? Java的io模型分为三种,(BIO,NIO,AIO),Netty现在主要推荐的(NIO...

  • nio

    参考文章 Java Nio Java NIO学习笔记 - NIO客户端时序图 Java NIO学习笔记 - NIO...

  • netty系列之(一)——netty介绍

    IO模型 一、NIO原理 Netty 是基于Java NIO 封装的网络通讯框架,只有充分理解了 Java NIO...

  • Java BIO与NIO

    网络IO模型 为了弄清JavaBIO(传统的 java.io 包)和NIO(Java 1.4 引入的 java.n...

  • 详解IO复用模型select,poll,epoll机制

    在Java中,主要有三种IO模型,分别是阻塞IO(BIO)、非阻塞IO(NIO)和 异步IO(AIO)。Java中...

  • java NIO 学习

    NIO是java1.4推出的一种全新的IO模型,全称是java non-blocking IO,提供ByteBuf...

网友评论

    本文标题:JAVA的NIO学习笔记第一节-Unix的IO模型

    本文链接:https://www.haomeiwen.com/subject/klqtoxtx.html