TCP三次握手協議是為了在不可靠的互聯網環境中可靠地建立起一個連接,三次握手可以確保兩端的發送和接收能力都是正常的。
那么,為什么是三次而不是二次或四次握手呢?
為什么不是二次握手?
如果是二次握手,即客戶端發送一個SYN到服務器,服務器回復一個SYN-ACK給客戶端,此時就建立連接。
這種情況下,如果第一個SYN請求在網絡中延遲了,并且客戶端重新發送了SYN后建立了連接,那么當延遲的SYN請求到達服務器后,服務器會認為是新的連接請求,而此時客戶端不會理會服務器的回應,導致服務器一直等待,浪費資源。
為什么不是四次握手?
四次握手會增加額外的延遲和復雜性,并且第四個握手并沒有提供三次握手已經解決的問題的任何額外保證。
三次握手已經能夠確認雙方的發送和接收能力都是正常的,進一步的確認只會增加一次往返時間,降低建立連接的效率。
三次握手建立連接的過程:
-
客戶端發送SYN:客戶端選擇一個隨機的序列號x發送一個SYN報文,并進入SYN_SENT狀態。
-
服務器發送SYN-ACK):服務器收到SYN報文,選擇自己的序列號y,并發送一個SYN-ACK報文,服務器進入SYN_RCVD狀態。
-
客戶端發送ACK:客戶端收到SYN-ACK報文后,會發送一個ACK報文,然后進入ESTABLISHED狀態。
數據傳輸結束之后的四次揮手:
TCP的連接終止則需要四次揮手,這是因為TCP連接是全雙工的,即通信雙方都可以同時發送和接收信息。終止連接時,每個方向都需要單獨關閉,所以就需要四次揮手。
-
客戶端發送FIN:客戶端決定數據發送完畢后,發送一個FIN報文。
-
服務器ACK:服務器收到這個FIN報文,發送一個ACK報文確認,并進入CLOSE_WAIT狀態。
-
服務器發送FIN:服務器準備好關閉連接時,發送一個FIN報文。
-
客戶端ACK:客戶端收到FIN后,發送一個ACK報文,然后進入TIME_WAIT狀態。經過一段時間后確保服務器收到ACK報文之后,客戶端關閉連接。
生活中的例子:
可以將三次握手比作電話通話。當你撥打一個電話號碼時,對方接聽(第一次握手),你們開始互相問候確認對方能聽到(第二次握手),然后你們開始對話(第三次握手)。
如果只問候一次,你可能不確定對方是否真的聽到你;如果問候多次,就顯得冗余和不效率。
通話結束后,你說“再見”掛斷電話(第一次揮手),對方說“再見”后也掛斷(第二次揮手),這樣確保了雙方都明白通話結束。
在電話通話快結束的時候:
你先說“你還什么別的嗎,沒有我就要掛了”(第一次揮手),等待對方回應,相當于發送了FIN包。
對方回應“等我想想還有什么”(第二次揮手),相當于對方發送了ACK包,但對方可能還有點兒事要處理,所以通話還未立刻結束。
過了一會兒,對方確認說“好了,我也沒話了,那掛了”(第三次揮手),這時候對方發送了FIN包。
你回應“知道了,掛了”(第四次揮手),對應發送ACK包,之后雙方都可以掛斷電話,結束通話。
求一鍵三連:點贊、分享、收藏
點贊對我真的非常重要!在線求贊,加個關注我會非常感激!@小鄭說編程