Netty權威指南:Linux網路 I/O 模型簡介

無敵天驕發表於2021-04-02

Linux的核心將所有外部裝置都看做一個檔案來操作,對一個檔案的讀寫操作會呼叫核心提供的系統命令,返回一個 file descriptor ( fd,檔案 描述符)。而對一個 socket的讀寫也會有相應的描述符,稱為 socketfd (  socket描述符),描述符就是一個數字,它指向核心中的一個結構體(檔案路徑,資料區等一些屬性)。

根據 UNIX網路程式設計對 I/O模型的分類, UNIX提供了5種 I/O模型,分別如下。

(1)阻塞I/O模型:

最常用的 I/O模型就是阻塞 I/O模型,預設情形下,所有檔案操作都是阻塞的。我們以套接字介面為例來講解此模型:在程式空間中呼叫 recvfrom,其系統呼叫直到資料包到達且被複制到應用程式的緩衝區中或者發生錯誤時才返回,在此期間一直會等待,程式在從呼叫 recvfrom開始到它返回的整段時間內都是被阻塞的,因此被稱為阻塞 I/O模型,如圖1-1所示。


Netty權威指南:Linux網路 I/O 模型簡介


(2)非阻塞I/O模型:

recvfrom從應用層到核心的時候,如果該緩衝區沒有資料的話,就直接返回一個 EWOULDBLOCK錯誤,一般都對非阻塞 I/O模型進行輪詢檢查這個狀態,看核心是不是有資料到來,如圖1-2所示。


Netty權威指南:Linux網路 I/O 模型簡介


(3) I/O複用模型:

Linux提供 select/poll, 程式透過將一 一個或多個fd傳遞給  select 或  poll 系統呼叫,阻塞在 select 操作.上,這樣 select/poll 可以幫我們偵測多個fd是否處於就緒狀態。 select/poll是順序掃描fd是否就緒,而且支援的fd數量有限,因此它的使用受到了一些制約。Linux 還提供了一個 epoll系統呼叫, epoll 使用基於事件驅動方式代替順序掃描,因此效能更高。當有fd就緒時,立即回撥函式 rollback,如圖1-3所示。


Netty權威指南:Linux網路 I/O 模型簡介


(4)訊號驅動I/O模型:

首先開啟套介面訊號驅動 I/O功能,並透過系統呼叫 sigaction執行一個訊號處理函式(此係統呼叫立即返回,程式繼續工作,它是非阻塞的)。當資料準備就緒時,就為該程式生成-一個 SIGIO訊號,透過訊號回撥通知應用程式呼叫 recvfrom來讀取資料,並通知主迴圈函式處理資料,如圖1-4 所示。


Netty權威指南:Linux網路 I/O 模型簡介


(5)非同步I/O:

告知核心啟動某個操作,並讓核心在整個操作完成後(包括將資料從核心複製到使用者自己的緩衝區)通知我們。這種模型與訊號驅動模型的主要區別是:訊號驅動I/O由核心通知我們何時可以開始一個 I/O操作;非同步 I/O 模型由核心通知我們 I/O 操作何時已經完成,如圖1-5所示。


Netty權威指南:Linux網路 I/O 模型簡介


如果想要了解更多的UNIX系統網路程式設計知識,可以閱讀《UNIX網路程式設計》,裡面有非常詳細的原理和API介紹。對於大多數Java程式設計師來說,不需要了解網路程式設計的底層細節,大家只需要有個概念,知道對於作業系統而言,底層是支援非同步I/O通訊的。只不過在很長一段時間Java並沒有提供非同步I/O通訊的類庫,導致很多原生的Java程式設計師對這塊兒比較陌生。當你瞭解了網路程式設計的基礎知識後,理解Java的NIO類庫就會更加容易一些。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69964492/viewspace-2766379/,如需轉載,請註明出處,否則將追究法律責任。

相關文章