Java Socket 工作機制

Socket 連接機制

主機 A 的應用程序要能和主機 B 的應用程序通信,必須通過 Socket 建立連接,而建立 Socket 連接必須由底層 TCP/IP 來建立TCP連接。TCP 是因特網中的傳輸層協議,使用三次握手協議建立連接。當請求方發出 SYN 連接請求後,等待對方回答 SYN+ACK ,並最終對對方的 SYN 執行 ACK(Acknowledgement確認字符)確認。

 

三次握手協議

第一次握手:客戶端發送 SYN(SEQ=x)報文給服務器端,進入 SYN_SEND 狀態。

第二次握手:服務器端收到 SYN 報文,迴應一個 SYN (SEQ=y)ACK(ACK=x+1)報文,進入 SYN_RECV 狀態。

第三次握手:客戶端收到服務器端的 SYN 報文,迴應一個 ACK(ACK=y+1)報文,進入 Established 已建立狀態。

 

Socket連接過程

客戶端

當客戶端要與服務端通信時,客戶端首先要創建一個 Socket 實例,操作系統將爲這個 Socket 實例分配一個沒有被使用的本地端口號,並創建一個包含本地地址、遠程地址和端口號的套接字數據結構,這個數據結構將一直保存在系統中直到這個連接關閉。

在創建 Socket 實例的構造函數正確返回前,將要進行 TCP 的三次握手協議,TCP握手完成後,Socket實例對象創建完成,否則拋出IOException。

服務端

與客戶端對應的服務端將創建一個 ServerSocket 實例。同時操作系統也會爲 ServerSocket 實例創建一個底層數據結構,包含指定監聽的端口號和監聽地址的通配符,之後當調用 accept() 方法時,將進入阻塞狀態,等待客戶端請求。

當請求到來時,將爲這個連接創建一個新的套接字數據結構,其中包含了請求源的地址和端口號。這個數據結構會關聯到ServerSocket 實例的一個未完成的連接列表中。注意此時服務端的 ServerSocket 實例還未創建完成,要等到與客戶端的三次握手完成後這個服務端的ServerSocket實例纔會返回,並將其對應的數據結構從未完成列表轉移到已完成列表。

數據傳輸

當連接建立成功後,客戶端和服務端都會擁有一個 Socket 實例,每個 Socket 實例都有一個 InputStream 和 OutputStream,並通過這兩個對象以字節流交換數據。

當創建 Socket 實例時,操作系統會爲 InputStream 和 OutputStream 分配一定大小的緩衝區,發送端將數據寫到 OutputStream的 SendQ 隊列中,當 SendQ 滿了,數據將被轉移到到另一端的 InputStream 的 RecvQ 隊列中,若 RecvQ 也滿了,那麼OutputStream 的 write 方法將阻塞,直到 RecvQ 有足夠空間容納 SendQ 發送的數據。若兩邊同時傳輸數據可能會產生死鎖。

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