
微信搜索:碼農StayUp
主頁地址:https://gozhuyinglong.github.io
原始碼分享:https://github.com/gozhuyinglong/blog-demos
在日常 Coding 中,多多少少都會接觸到網路 IO,就會想要深入了解一下,看了很多文章,總是云里霧里的感覺,直到讀了《UNIX網路編程 卷1:套接字聯網API》中的介紹后,才豁然開朗,這里就給大家分享一下,如有不對,歡迎指出,
1. 概念說明
為了便于理解后面的內容,我們先來了解一些概念,
1.1 Socket
Socket 中文翻譯為套接字,是計算機網路中行程間進行雙向通信的端點的抽象,一個 Socket 代表了網路通信的一端,是由作業系統提供的行程間通信機制,
-
在作業系統中,通常會為應用程式提供一組應用程式介面,稱為 Socket 介面(Socket API),應用程式可以通過 Socket 介面,來使用網路 Socket,以進行資料的傳輸,
-
一個 Socket 由IP地址和埠組成,即:Socket 地址 = IP地址 : 埠號,
-
在同一臺計算機上,TCP 協議與 UDP 協議可以同時使用相同的埠(Port),而互不干擾,
-
要想實作網路通信,至少需要一對 Socket,其中一個運行在客戶端,稱之為 Client Socket;另一個運行在服務器端,稱之為 Server Socket,
-
Socket 之間的連接程序可以分為三個步驟:(1)服務器監聽;(2)客戶端連接;(3)連接確認,

1.2 Socket 緩沖區
每個 Socket 被創建后,都會在內核中分配兩個緩沖區:輸入緩沖區和輸出緩沖區,
-
通過 Socket 發送資料并不會立即向網路中傳輸資料,而是先將資料寫入到輸出緩沖區中,再由 TCP 協議將資料從輸出緩沖區發送到目標主機,
-
通過 Socket 接收資料也是如此,也是從輸入緩沖區中讀取資料,而不是直接從網路中讀取,

1.3 用戶空間、內核空間、系統呼叫
作業系統的行程空間可以分為用戶空間(User Space)和內核空間(Kernel Space),它們需要不同的執行權限,
-
大多數系統互動式操作需要在內核空間中運行,比如設備 IO 操作,
-
我們的應用程式運行在用戶空間,是不具備系統級的直接操作權限的,如果應用程式想要訪問系統核心功能,必須通過系統呼叫(System Call)來完成,比如呼叫
recv()函式,會將輸入緩沖區中的內容拷貝到用戶緩沖區, -
系統呼叫運行在內核空間,是作業系統為應用程式提供的介面,

下面列舉了一些 Linux 作業系統中的系統呼叫介面(部分函式后面章節會用到):
-
socketcall socket系統呼叫
-
socket 建立socket
-
bind 系結socket到埠
-
connect 連接遠程主機
-
accept 回應socket連接請求
-
send 通過socket發送資訊
-
sendto 發送UDP資訊
-
recv 通過socket接收資訊
-
recvfrom 接收UDP資訊
-
listen 監聽socket埠
-
select 對多路同步IO進行輪詢
-
shutdown 關閉socket上的連接
-
sigaction 設定對指定信號的處理方法
1.4 阻塞與非阻塞
阻塞與非阻塞,用于描述呼叫者在等待回傳結果時的狀態,
-
阻塞:呼叫者發起請求后,會一直等待回傳結果,這期間當前執行緒會被掛起(阻塞),
-
非阻塞:呼叫者發起請求后,會立刻回傳,當前執行緒也不會阻塞,該呼叫不會立刻得到結果,呼叫者需要定時輪詢查看處理狀態,
1.5 同步與異步
而同步與異步,用于描述呼叫結果的回傳機制(或者叫通信機制),
-
同步:呼叫者發起請求后,會一直等待回傳結果,即由呼叫者主動等待這個呼叫結果,
-
異步:呼叫者發起請求后,會立刻回傳,但不會立刻得到這個結果,而是由被調者在執行結束后主動通知(如 Callback)呼叫者,
2. 五種 IO 模型
IO 模型是指:用什么樣的通道或者說是通信模式進行資料的傳輸,這很大程式上決定了程式通信的性能,
Linux 系統為我們提供五種可用的 IO 模型:阻塞式 IO 模型、非阻塞式 IO 模型、IO 多路復用模型、信號驅動 IO 模型和異步 IO 模型,
2.1 阻塞式 IO 模型
阻塞式 IO (Blocking IO):應用行程從發起 IO 系統呼叫,至內核回傳成功標識,這整個期間是處于阻塞狀態的,

2.2 非阻塞式 IO 模型
非阻塞式IO(Non-Blocking IO):應用行程可以將 Socket 設定為非阻塞,這樣應用行程在發起 IO 系統呼叫后,會立刻回傳,應用行程可以輪詢的發起 IO 系統呼叫,直到內核回傳成功標識,

2.3 IO 多路復用模型
IO 多路復用(IO Multiplexin):可以將多個應用行程的 Socket 注冊到一個 Select(多路復用器)上,然后使用一個行程來監聽該 Select(該操作會阻塞),Select 會監聽所有注冊進來的 Socket,只要有一個 Socket 的資料準備好,就會回傳該Socket,再由應用行程發起 IO 系統呼叫,來完成資料讀取,

2.4 信號驅動 IO 模型
信號驅動 IO(Signal Driven IO):可以為 Socket 開啟信號驅動 IO 功能,應用行程需向內核注冊一個信號處理程式,該操作并立即回傳,當內核中有資料準備好,會發送一個信號給應用行程,應用行程便可以在信號處理程式中發起 IO 系統呼叫,來完成資料讀取了,

2.5 異步 IO 模型
異步 IO(Asynchronous IO): 應用行程發起 IO 系統呼叫后,會立即回傳,當內核中資料完全準備后,并且也復制到了用戶空間,會產生一個信號來通知應用行程,

3. 總結
從上述五種 IO 模型可以看出,應用行程對內核發起 IO 系統呼叫后,內核會經過兩個階段來完成資料的傳輸:
-
第一階段:等待資料,即應用行程發起 IO 系統呼叫后,會一直等待資料;當有資料傳入服務器,會將資料放入內核空間,此時資料準備好,
-
第二階段:將資料從內核空間復制到用戶空間,并回傳給應用程式成功標識,

前四種模型的第二階段是相同的,都是處于阻塞狀態,其主要區別在第一階段,而異步 IO 模型則不同,應用行程在這兩個階段是完全不阻塞的,
| IO 模型 | 第一階段 | 第二階段 |
|---|---|---|
| 阻塞式IO | 阻塞 | 阻塞 |
| 非阻塞式IO | 非阻塞 | 阻塞 |
| IO多路程復用 | 阻塞(Select) | 阻塞 |
| 信號驅動式IO | 異步 | 阻塞 |
| 異步IO | 異步 | 異步 |
參考資料
- UNIX網路編程 卷1:套接字聯網API
推薦閱讀
-
36張圖詳解網路基礎知識
-
75張圖帶你了解網路設備、網路地址規劃、靜態路由、實戰演練

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/280277.html
標籤:其他
