Linux網絡IO模型及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操作。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章