TCP 協議的三次握手

TCP 三次握手是一個很經典的問題,這裏簡單的整理一下 TCP 可以成功完成三次握手的流程。

Socket API 的流程
在進行 Socket 編程的時候,服務器端通常使用 socket、bind、listen 這三個 API 函數創建一個被動套接字,然後通過 accept 函數等待客戶端的連接,調用 accept 函數後,程序會進行阻塞等待。

客戶端通過 socket、connect 兩個 API 函數來創建套接字,並針對服務器端發起連接。

在連接服務器端時,整個工作是網絡協議進行完成的,並不是由 accept 和 connect 函數真正去完成的,它們只是網絡編程的接口,真正做這些事情的是 網絡協議,包括同來發送和接收數據的通信,真正完成工作的也是 網絡協議 而並不是 send 和 recv 等相關的 API 函數。

三次握手的過程
上面提到,服務端已經處於 accept 函數的阻塞狀態等待客戶端的連接,而客戶端調用了 connect 函數要連接服務器端了,此時雙方開始進行三次握手,整個握手過程對於程序員來說是透明的。也就是說,程序員只需要去調用相關的 API 函數,而不用去關心具體建立連接的細節。

整個建立握手的過程是由客戶端發起的,因爲服務器是被動等待的狀態,不會主動發起和客戶端的連接。
1、客戶端的協議棧向服務器端發送了 SYN 包,並告訴服務器端當前發送序列號 x,客戶端進入 SYNC_SENT 狀態;
2、服務器端的協議棧收到 SYN 包之後,向客戶端進行 ACK 應答,應答的值爲 x + 1,表示對 SYN 包 x 的確認,同時服務器也發送一個 SYN 包,告訴客戶端當前我的發送序列號爲 y,服務器端進入 SYNC_RCVD 狀態;
3、客戶端協議棧收到服務器端發來的 ACK 包之後,使得應用程序從 connect 調用返回,表示客戶端到服務器端的單向連接建立成功,客戶端的狀態爲 ESTABLISHED,同時客戶端協議棧也會對服務器端發送 ACK 包進行應答,應答數據爲 y + 1;
4、客戶端發送的 ACK 包到達服務器端後,服務器端協議棧使得 accept 阻塞調用返回,這個時候服務器端到客戶端的單向連接也建立成功,服務器端也進入 ESTABLISHED 狀態。

在第 2 步中,其實完成了兩個動作,第 1 個動作是,服務端要向客戶端發送一個 ACK 包用以進行確認,第 2 個動作是,服務器端要向客戶端發送一個 SYN 包用來和客戶端完成同步請求。這兩個步驟分別使用了 TCP 協議的 SYN 標誌和 ACK 標誌,如果發送兩個包去完成就會顯得多餘,因此兩個動作實際是在一個包內就完成了。

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