[Java]I/O底層原理之二:Socket工作機制
阿新 • • 發佈:2017-09-03
tcp連接 fin 連接建立 src 並發 如果 send rec 轉換
一、TCP狀態轉化
TCP連接的狀態轉換圖如下
註:SYN 表示建立鏈接、FIN 表示關閉鏈接、ACK 表示響應、PSH 表示有數據傳輸、RST 表示鏈接重置。
- CLOSED:初始狀態,在超時或連接關閉時也會進入此狀態。
- LISTEN:服務端在等待連接時的狀態。
- SYN-SENT:客戶端發起連接並發送 SYN 給服務端後等待的狀態。如果不能連接,則進入 CLOSED 狀態。
- SYN-RCVD:服務端接受客戶端的 SYN 請求,由 LISTEN 狀態進入此狀態。同時回應一個 SYN、ACK 給客戶端。
- ESTABLISHED:數據傳輸狀態,服務端和客戶端建立連接後的狀態。
- FIN-WAIT-1:主動關閉的一方進入此狀態。等待遠程TCP連接中斷請求,或先前的連接中斷請求的確認
- FIN-WAIT-2:主動關閉的一方接收另一方的 FIN ACK進入的狀態。
- CLOSE-WAIT:被動關閉的一方收到 FIN 後進入的狀態,接收到 FIN 的同時發送 ACK。
- LAST-ACK:被動關閉的一方發起關閉請求。
- CLOSING:
- TIME-WAIT:
1 建立連接的步驟(三次握手)
- 客戶端發送 SYN 給服務端
- 服務端回應 ACK 和 SYN 給客戶端
- 客戶端發送 ACK 給服務端
2 斷開鏈接的步驟(四次揮手)
- 客戶端發送 FIN 給服務端
- 服務端回應 ACK
- 服務端關閉鏈接,發送 FIN 給客戶端
- 客戶端回應 ACK 給服務端
二、Socket
一個 Socket 實例代表了一個通信鏈路,當連接建立成功後,服務器和客戶端都會各擁有一個 Socket 實例,且這兩個實例都會擁有一個 InputStream 和 OutputStream,以此來傳輸數據。在 InputStream 和 OutputStream 中會各有一個緩存區,數據寫入和讀取都是通過這個緩存區完成的。通過 OutputStream 將數據寫入到其 SendQ 隊列中,當隊列填滿時,數據將被傳遞到 InputStream 的 RecvQ 隊列中,如果這時 RecvQ 已滿,則 OutputStream 的 write() 方法將會阻塞,直到 RecvQ 隊列有足夠空間容納 SendQ 發送的數據。要註意的是,緩存區的大小及讀寫宿舍非常影響連接的傳輸效率,而且由於是阻塞式,如果兩遍同時傳遞數據有可能發生死鎖。
Socket源碼分析:
public Socket() // 創建一個無連接的socket
public Socket(Proxy proxy) //
[Java]I/O底層原理之二:Socket工作機制