Linux网络IO模型及JAVA中IO模型

文章目录

  • 1.概述
  • 2.Linux网络IO模型
    • 2.1.阻塞IO模型
    • 2.2.非阻塞IO模型
    • 2.3.IO复用模型
      • 2.3.1.select
      • 2.3.2.poll
      • 2.3.3.epoll
    • 2.4.信号驱动IO模型
    • 2.5.异步IO
  • 3.JAVA中IO模型

1.概述

在jdk1.4之前JAVA只有同步阻塞IO,在jdk1.4版本更新同步非阻塞的NIO,在jdk1.7又更新了异步的NIO2.0,本文将简单介绍下Linux有哪些网络IO模型,以及JAVA中的IO所对应的网络IO模型。
理解本文之前需要先知道一个概念:用户空间与内核空间,即对于一次IO操作,会先将数据拷贝到系统内核缓冲区,然后从内核缓冲区拷贝到用户空间的程序缓冲区。
recvfrom函数:此函数主要用于Linux内核从指定socket接收数据包并存储到内核缓冲区,可以用在已经建立连接的socket,也可以用在没有建立连接的socket。

2.Linux网络IO模型

Linu内核将所有外部设备都看做是文件操作。对一个文件的读写操作会调用内核提供的系统命令,返回一个file descriptor(fd,文件描述符),可以理解为fd是内核为文件创建的索引。而对socket的读写也会有相应的描述符,称为socketfd(socket 描述符),描述符就是一个数字,它指向内核中的一个结构体。Linux根据分类,提供了5种IO模型,如下:

2.1.阻塞IO模型

阻塞模型的IO请求过程如下:

  1. 进程调用recvfrom函数并等待数据包到达(进程阻塞等待)
  2. 数据包从内核被复制到进程的缓冲区或者发生错误返回(进程阻塞等待)

整个过程进程都处于被阻塞状态,故被称为阻塞IO。
默认情况下,所有的文件操作都是阻塞的。

2.2.非阻塞IO模型

非阻塞模型的IO请求过程如下:

  1. 进程调用recvfrom函数如果没有数据包,直接返回EWOULDBLOCK错误
  2. 轮训(1)过程
  3. 数据包从内核被复制到进程的缓冲区(进程阻塞等待)

2.3.IO复用模型

I/O多路复用就是通过一种机制,使一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。Linux提供了三种方式:select、poll、epoll

2.3.1.select

IO请求过程如下:

  1. 进程发起select调用,select遍历所有fd,监测fd状态(进程阻塞在select)
  2. fd读/写就绪时,通知进程读/写条件,进程发起recvfrom
  3. 数据包从内核被复制到进程的缓冲区(进程阻塞等待)

select特点

  • select目前几乎在所有的平台上支持,跨平台支持比较好。
  • select是顺序扫描fd,而且单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但是这样也会造成效率的降低。
  • select机制中提供了一种fd_set的数据结构,实际上是一个long数组。select使用了三个位图来表示三个fdset的方式.

2.3.2.poll

poll和select的实现基本是一致,只是数据传递格式不太一样。 与select函数一样,poll也是通过顺序轮训所有fd来获取就绪的描述符,如果存在大量的非活跃状态的fd,则轮训过程也浪费了一定的开销。

2.3.3.epoll

epoll是在2.6内核中提出的。
epoll特点

  • 相对于select和poll来说,epoll更加灵活,没有描述符限制。
  • epoll采用基于事件的就绪通知方式,一旦某个fd就绪,则采用callback方式通知进程。
  • epoll不用轮训所有的fd,epoll每次只遍历活跃的fd,因此在活跃的fd较少的情况下很有优势,如果大量的fd都处于活跃状态,则epoll的效率可能不如select或poll。

2.4.信号驱动IO模型

请求过程如下:

  1. 开启信号驱动IO功能,调用sigaction执行一个信号处理函数,并立即返回
  2. 内核收到数据包则生成一个sigio信号通知进程
  3. 进程收到sigio信号后,调用recvfrom函数
  4. 数据包从内核被复制到进程的缓冲区(进程阻塞等待)

2.5.异步IO

请求过程:

  1. 进程发起IO操作,通知内核并立即返回
  2. 内核收到数据包后生成一个sigio信号通知进程
  3. 内核数据包从内核被复制到进程的缓冲区并通知进程

3.JAVA中IO模型

JDK1.4之前使用的都是同步阻塞的BIO(阻塞IO模型)。
JDK1.4发布的NIO特点:

  • IO模型使用的是LInux的多路复用IO模型中的epoll
  • 引入了缓冲区ByteBuffer、管道Pipe、通道Channel、文件通道FileChannel、多种字符集编解码、基于Perl实现的正则表达式类库等。

JDK1.7对NIO进行了升级更新,称为NIO2.0,特点如下:

  • 提供了标准文件系统的SPI。
  • 能够批量获取文件属性的API。
  • 提供AIO,支持基于文件和socket的异步IO操作。

你可能感兴趣的:(JAVA,Linux)