面試官:說一下TCP三次握手的過程
參考面試回答:
-
在第一次握手的時候、客戶端會隨機生成初始化序號、放到TCP報文頭部的序號字段中、同時把SYN標志設置為1 這樣就表示SYN報文(這里是請求報文)。客戶端將報文放入 TCP 報文首部的序列號字段中。接著把這個SYN報文發送給服務端、之后客戶端處于
SYN_SENT
狀態。這是第一次握手。 -
然后第二次握手的時候:服務端收到SYN報文后、首先服務端也會隨機生成初始化序號、放到TCP報文頭部的序號字段中、然后對客戶端的初始化序號+1作為確認號、放到TCP報文頭部的確認應答字段中、并將SYN和ACK標志設置為1,這樣就表示SYN-ACK報文、然后把該報文發給客戶端、之后服務端處于SYN_RCVD狀態。這是第二次握手
-
最后來到第三次握手的過程:客戶端收到服務端SYN-ACK報文后:客戶端會回一個ACK確認報文、該報文的確認號是服務端的初始化序號+1、并且ACK標志會設置為1。表示這是一個確認報文。這是第三次握手
-
之后客戶端處于ESTABLISHED狀態。
-
服務端收到ACK確認報文后、服務端也進入處于
ESTABLISHED
狀態。以上就是TCP三次握手的過程。
客戶端 服務器| || SYN ----------------------> || |SYN_SENT || || <------ SYN-ACK ------------ || || ACK ----------------------> || |ESTABLISHED ESTABLISHED
為什么需要三次握手 兩次不行嗎
-
分析:面試的時候、最好說出兩個原因,并且要解釋一下為什么2次握手就不行。把面試官當做小白、講到他理解這個問題的原因。
-
分析回答:
-
我的理解主要有兩個原因:
-
第一個原因是、三次握手可以有效防止歷史連接的建立、避免資源浪費。假設網絡中殘留一個序號為90的SYN報文、現在客戶端向服務端發起了建立連接的請求、發送了一個序號為100的SYN報文、如果這時候服務端先收到的是序號為90的SYN報文、就代表收到了歷史連接、這時候服務端會回復確認號為90+1的SYN-ACK報文、客戶端收到后、發現其實自己期望收到的確認號是100+1、而不是90+1、所以會斷開連接、并且回RST給服務端、服務端收到RST也就會斷開連接了、這樣就避免了歷史連接的建立。
-
如果使用兩次握手、服務器收到客戶端的SYN報文后會立即建立連接。但服務器無法區分該SYN報文是新的連接請求、還是延遲到達的歷史報文、如果收到的是歷史SYN報文、服務器也會誤以為是新的連接請求、并分配資源建立連接、造成資源浪費。這會導致服務器為無效的歷史連接分配資源、造成浪費。
-
如果是三次握手
-
由于客戶端收到的確認號是 91、與期望的 101 不符、客戶端意識到這是一個歷史連接的響應
-
客戶端發送一個 RST 報文給服務器、告訴服務、這是一個錯誤的連接、請斷開
-
服務器收到 RST 報文后、會斷開連接、釋放資源。
-
-
-
第二個原因是、三次握手可以確認客戶端和服務端是否同時具備發送和接收的能力。第一次握手代表客戶端具有發送能力、當服務端收到第一次握手并且響應了第二次握手、實際上這里就證明了服務端具有發送和接收的能力。客戶端收到了第二次握手、然后響應了第三次握手、才代表客戶端有接收的能力。如果是兩次握手的話、只能證明服務端具有發送和接收能力、以及客戶端的發送能力、但是無法證明客戶端具有接收的能力。
-
三次握手的意義:
-
第一次握手 (SYN): 客戶端發送 SYN 報文、表明客戶端具有 發送 能力。
-
第二次握手 (SYN-ACK): 服務器收到 SYN 報文并回復 SYN-ACK 報文、表明服務器具有 接收 和 發送 能力。
-
第三次握手 (ACK): 客戶端收到 SYN-ACK 報文并回復 ACK 報文、表明客戶端具有 接收 能力。
-
通過三次握手可以確保客戶端和服務端都具備雙向通信的能力。
-
-
兩次握手的缺陷: 兩次握手只能確認服務器的發送和接收能力、以及客戶端的發送能力、但無法確認客戶端的接收能力。
-
以上就是我覺得TCP需要三次握手的原因。
參考面試回答:
我的理解主要有兩個原因:
1.防止歷史連接的建立、避免資源浪費
三次握手可以有效防止歷史連接的建立、避免服務器為過期的連接分配資源。
在沒有三次握手的情況下、服務器無法區分是新的連接請求還是之前連接的殘留報文。
如果客戶端發送了一個連接請求、服務器無法判斷它是否是一個新的連接、可能會誤以為這是一個有效的請求、進而分配資源。
但如果連接請求是歷史報文、那么服務器響應客戶端時、也就是客戶端收到第二次握手的時候、客戶端會發現確認號與預期不符、并會主動終止連接、發送 RST 報文通知服務器。這里也就是第三次握手的過程會發送一個RST重置報文給服務器。服務器收到 RST 報文后、會斷開連接并釋放資源。這樣可以避免無效連接占用資源。
2.確保雙方都具備發送和接收的能力
第二個原因是:三次握手可以確認客戶端和服務端是否同時具備發送和接收的能力。第一次握手代表客戶端具有發送能力、當服務端收到第一次握手并且響應了第二次握手、實際上這里就證明了服務端具有發送和接收的能力。客戶端收到了第二次握手、然后響應了第三次握手、才代表客戶端有接收的能力。如果是兩次握手的話、只能證明服務端具有發送和接收能力、以及客戶端的發送能力、但是無法證明客戶端具有接收的能力。
介紹一下TCP四次揮手
分析:
-
問題:TCP四次揮手的過程
-
客戶端FIN->服務端ACK ->服務端FIN ->客戶端ACK
-
分析:要把每個階段的TCP狀態說出來。雙方都都可以主動斷開連接,下圖是客戶端主動斷開連接的過程:
-
客戶端打算關閉連接、此時會發送一個
FIN
報文、之后客戶端進入FIN_WAIT_1
狀態。 -
服務端收到FIN報文后、就向客戶端發送ACK應答報文、接著服務端進入
CLOSE_WAIT
狀態。 -
客戶端收到服務端的ACK應答報文后、之后進入
FIN_WAIT_2
狀態。 -
等待服務端處理完數據后、也向客戶端發送FIN報文、之后服務端進入
LAST_ACK
狀態。 -
客戶端收到服務端的FIN報文后、回一個
ACK
應答報文、之后進入TIME_WAIT
狀態。 -
服務端收到了ACK應答報文后、就進入了
CLOSE
狀態、至此服務端已經完成連接的關閉。 -
客戶端在
TIME_WAIT
狀態經過2MSL一段時間后、自動進入CLOSE
狀態、至此客戶端也完成連接的關閉。
-
-
總結:以上就是四次揮手的過程、每個方向都需要一個
FIN
和一個ACK
、因此通常被稱為四次揮手。
參考面試回答:
-
第一次揮手:客戶端打算關閉連接、此時會發送一個FIN報文、用來關閉客戶端到服務端的數據傳送、并進入
FIN_WAIT_1
狀態。 FIN報文會攜帶一個序列號。 -
第二次揮手: 服務端收到FIN報文后、就向客戶端發送ACK應答報文、確認收到了客戶端的關閉請求。 ACK報文會攜帶確認序列號、表示服務端已經正確接收了客戶端發送的FIN報文。 服務端進入
CLOSE_WAIT
狀態。 -
客戶端收到服務端的ACK應答報文后、進入
FIN_WAIT_2
狀態、等待服務端發送FIN報文。此時、客戶端到服務端的連接已經釋放、客戶端不再發送數據、但服務端仍然可以向客戶端發送數據。 -
第三次揮手: 等服務端處理完數據后、也向客戶端發送
FIN
報文、用來關閉服務端到客戶端的數據傳送、并進入LAST_ACK
狀態。 -
第四次揮手: 客戶端收到服務端的FIN報文后、回一個
ACK
應答報文、確認收到了服務端的關閉請求。 客戶端進入TIME_WAIT
狀態。 -
服務端收到了ACK應答報文后、就進入了
CLOSE
狀態、至此服務端已經完成連接的關閉。 -
客戶端在
TIME_WAIT
狀態經過2MSL(Maximum Segment Lifetime)一段時間后、自動進入CLOSE
狀態、至此客戶端也完成連接的關閉。