Java高級網絡編程—Socket、同步/異步、阻塞/非阻塞、BIO編程、NIO編程、AIO編程

一、網絡編程基礎原理

1 網絡編程(Socket)概念

首先注意,Socket不是Java中獨有的概念,而是一個語言無關標準。任何可以實現網絡編程的編程語言都有Socket。

1.1 什麼是Socket

網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱爲一個socket。
建立網絡通信連接至少要一個端口號。socket本質是編程接口(API),對TCP/IP的封裝,TCP/IP也要提供可供程序員做網絡開發所用的接口,這就是Socket編程接口;HTTP是轎車,提供了封裝或者顯示數據的具體形式;Socket是發動機,提供了網絡通信的能力。

Socket的英文原義是“孔”或“插座”。作爲BSD UNIX的進程通信機制,取後一種意思。通常也稱作"套接字",用於描述IP地址和端口,是一個通信鏈的句柄,可以用來實現不同虛擬機或不同計算機之間的通信。在Internet上的主機一般運行了多個服務軟件,同時提供幾種服務。每種服務都打開一個Socket,並綁定到一個端口上,不同的端口對應於不同的服務。Socket正如其英文原義那樣,像一個多孔插座。一臺主機猶如佈滿各種插座的房間,每個插座有一個編號,有的插座提供220伏交流電, 有的提供110伏交流電,有的則提供有線電視節目。 客戶軟件將插頭插到不同編號的插座,就可以得到不同的服務。

1.2 Socket連接步驟

根據連接啓動的方式以及本地套接字要連接的目標,套接字之間的連接過程可以分爲三個步驟:服務器監聽,客戶端請求,連接確認。【如果包含數據交互+斷開連接,那麼一共是五個步驟】

(1)服務器監聽:是服務器端套接字並不定位具體的客戶端套接字,而是處於等待連接的狀態,實時監控網絡狀態。

(2)客戶端請求:是指由客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。爲此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然後就向服務器端套接字提出連接請求。

(3)連接確認:是指當服務器端套接字監聽到或者說接收到客戶端套接字的連接請求,它就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,連接就建立好了。而服務器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連接請求。

1.3 Java 中的Socket

在java.net 包是網絡編程的基礎類庫。其中ServerSocket 和Socket 是網絡編程的基礎類
型。ServerSocket 是服務端應用類型。Socket 是建立連接的類型。當連接建立成功後,服務
器和客戶端都會有一個Socket 對象示例,可以通過這個Socket 對象示例,完成會話的所有
操作。

對於一個完整的網絡連接來說,Socket 是平等的,沒有服務器客戶端分級情況。 

2 什麼是同步和異步

同步和異步是針對應用程序和內核的交互而言的,同步指的是用戶進程觸發IO 操作並
等待或者輪詢的去查看IO 操作是否就緒,而異步是指用戶進程觸發IO 操作以後便開始做自
己的事情,而當IO 操作已經完成的時候會得到IO 完成的通知。
以銀行取款爲例:

同步 : 自己親自出馬持銀行卡到銀行取錢(使用同步IO 時,Java 自己處理IO 讀寫);

異步 : 委託一小弟拿銀行卡到銀行取錢,然後給你(使用異步IO 時,Java 將IO 讀寫
委託給OS 處理,需要將數據緩衝區地址和大小傳給OS(銀行卡和密碼),OS 需要支持異步IO
操作API);

3 什麼是阻塞和非阻塞

阻塞和非阻塞是針對於進程在訪問數據的時候,根據IO操作的就緒狀態來採取的不同方式,說白了是一種讀取或者寫入操作方法的實現方式,阻塞方式下讀取或者寫入函數將一直等待,而非阻塞方式下,讀取或者寫入方法會立即返回一個狀態值。

以銀行取款爲例:

阻塞 : ATM排隊取款,你只能等待(使用阻塞IO時,Java調用會一直阻塞到讀寫完成才返回);
非阻塞 : 櫃檯取款,取個號,然後坐在椅子上做其它事,等號廣播會通知你辦理,沒到號你就不能去,你可以不斷問大堂經理排到了沒有,大堂經理如果說還沒到你就不能去(使用非阻塞IO時,如果不能讀寫Java調用會馬上返回,當IO事件分發器通知可讀寫時再繼續進行讀寫,不斷循環直到讀寫完成)

4 BIO編程

Blocking IO: 同步阻塞的編程方式。

BIO編程方式通常是在JDK1.4版本之前常用的編程方式。編程實現過程爲:首先在服務端啓動一個ServerSocket來監聽網絡請求,客戶端啓動Socket發起網絡請求,默認情況下ServerSocket回建立一個線程來處理此請求,如果服務端沒有線程可用,客戶端則會阻塞等待或遭到拒絕。

且建立好的連接,在通訊過程中,是同步的。在併發處理效率上比較低。大致結構如下:

 同步並阻塞,服務器實現模式爲一個連接一個線程,即客戶端有連接請求時服務器端就需要啓動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,當然可以通過線程池機制改善。

BIO方式適用於連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,併發侷限於應用中,JDK1.4以前的唯一選擇,但程序直觀簡單易理解。

使用線程池機制改善後的BIO模型圖如下:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章