三次握手和四次揮手(面試必問)

2022-06-19 10:00:11 字數 3824 閱讀 9968

當面試官問你為什麼需要有三次握手、三次握手的作用、講講三次握手的時候,我想很多人會這樣回答:

首先很多人會先講下握手的過程:

1、第一次握手:客戶端給伺服器傳送乙個 syn 報文。

2、第二次握手:伺服器收到 syn 報文之後,會應答乙個 syn+ack 報文。

3、第三次握手:客戶端收到 syn+ack 報文之後,會回應乙個 ack 報文。

4、伺服器收到 ack 報文之後,三次握手建立完成。

作用是為了確認雙方的接收與傳送能力是否正常。

這裡我順便解釋一下為啥只有三次握手才能確認雙方的接受與傳送能力是否正常,而兩次卻不可以:

第一次握手:客戶端傳送網路包,服務端收到了。這樣服務端就能得出結論:客戶端的傳送能力、服務端的接收能力是正常的。

第二次握手:服務端發包,客戶端收到了。這樣客戶端就能得出結論:服務端的接收、傳送能力,客戶端的接收、傳送能力是正常的。不過此時伺服器並不能確認客戶端的接收能力是否正常。

第三次握手:客戶端發包,服務端收到了。這樣服務端就能得出結論:客戶端的接收、傳送能力正常,伺服器自己的傳送、接收能力也正常。

因此,需要三次握手才能確認雙方的接收與傳送能力是否正常。

這樣回答其實也是可以的,但我覺得,這個過程的我們應該要描述的更詳細一點,因為三次握手的過程中,雙方是由很多狀態的改變的,而這些狀態,也是面試官可能會問的點。所以我覺得在回答三次握手的時候,我們應該要描述的詳細一點,而且描述的詳細一點意味著可以扯久一點。加分的描述我覺得應該是這樣:

剛開始客戶端處於 closed 的狀態,服務端處於 listen 狀態。然後

1、第一次握手:客戶端給服務端發乙個 syn 報文,並指明客戶端的初始化序列號 isn(c)。此時客戶端處於 syn_send 狀態。

2、第二次握手:伺服器收到客戶端的 syn 報文之後,會以自己的 syn 報文作為應答,並且也是指定了自己的初始化序列號 isn(s),同時會把客戶端的 isn + 1 作為 ack 的值,表示自己已經收到了客戶端的 syn,此時伺服器處於 syn_revd 的狀態。

3、第三次握手:客戶端收到 syn 報文之後,會傳送乙個 ack 報文,當然,也是一樣把伺服器的 isn + 1 作為 ack 的值,表示已經收到了服務端的 syn 報文,此時客戶端處於 establised 狀態。

4、伺服器收到 ack 報文之後,也處於 establised 狀態,此時,雙方以建立起了鏈結。

ps:(1)syn=1 表示該報文不攜帶資料,但消耗乙個序號 seq=x,seq=x是客戶端的初始化序列號,因為tcp是面向位元組流的

(2)syn=1 表示該報文不攜帶資料,但消耗乙個序號 seq=y,seq=y是伺服器的初始化序列號,ack=1是乙個確認號

ack=x+1,表示伺服器下次接收到的序號希望是x+1。然後伺服器進入到syn-rcvd等待的狀態

(3)ack=1是乙個確認號,seq=x+1是上一次伺服器回應的序號要求,ack=y+1表示客戶下一次接收到的序號希望是y+1

三次握手的作用

三次握手的作用也是有好多的,多記住幾個,保證不虧。例如:

1、確認雙方的接受能力、傳送能力是否正常。

2、指定自己的初始化序列號,為後面的可靠傳送做準備。

3、如果是 https 協議的話,三次握手這個過程,還會進行數字證書的驗證以及加密金鑰的生成到。

單單這樣還不足以應付三次握手,面試官可能還會問一些其他的問題,例如:

1、(isn)是固定的嗎?

三次握手的乙個重要功能是客戶端和服務端交換isn(initial sequence number), 以便讓對方知道接下來接收資料的時候如何按序列號組裝資料。

如果isn是固定的,攻擊者很容易猜出後續的確認號,因此 isn 是動態生成的。

2、什麼是半連線佇列

伺服器第一次收到客戶端的 syn 之後,就會處於 syn_rcvd 狀態,此時雙方還沒有完全建立其連線,伺服器會把此種狀態下請求連線放在乙個佇列裡,我們把這種佇列稱之為半連線佇列。當然還有乙個全連線佇列,就是已經完成三次握手,建立起連線的就會放在全連線佇列中。如果佇列滿了就有可能會出現丟包現象。

這裡在補充一點關於syn-ack 重傳次數的問題: 伺服器傳送完syn-ack包,如果未收到客戶確認包,伺服器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次重傳,如果重傳次數超 過系統規定的最大重傳次數,系統將該連線資訊從半連線佇列中刪除。注意,每次重傳等待的時間不一定相同,一般會是指數增長,例如間隔時間為 1s, 2s, 4s, 8s, …

3、三次握手過程中可以攜帶資料嗎

很多人可能會認為三次握手都不能攜帶資料,其實第三次握手的時候,是可以攜帶資料的。也就是說,第一次、第二次握手不可以攜帶資料,而第三次握手是可以攜帶資料的。

為什麼這樣呢?大家可以想乙個問題,假如第一次握手可以攜帶資料的話,如果有人要惡意攻擊伺服器,那他每次都在第一次握手中的 syn 報文中放入大量的資料,因為攻擊者根本就不理伺服器的接收、傳送能力是否正常,然後瘋狂著重** syn 報文的話,這會讓伺服器花費很多時間、記憶體空間來接收這些報文。也就是說,第一次握手可以放資料的話,其中乙個簡單的原因就是會讓伺服器更加容易受到攻擊了。

而對於第三次的話,此時客戶端已經處於 established 狀態,也就是說,對於客戶端來說,他已經建立起連線了,並且也已經知道伺服器的接收、傳送能力是正常的了,所以能攜帶資料頁沒啥毛病。

為什麼要進行三次握手?

當進行第一次握手,網路不好可能會堵塞,所以連線的請求並沒有到達伺服器端;

但是tcp連線有超時重傳的機制,所以再一次傳送請求,這時候伺服器端接收到了你的請求,他也會返回乙個請求給你,這是第二次握手;

但是這時候網路環境突然又好了起來,那個堵塞的請求到達了伺服器端,伺服器端又給你回了乙個請求,但是你又不想給伺服器傳送請求,這時候伺服器的資源會進行占用等待你的請求,為了不使伺服器的資源繼續占用,你又必須傳送乙個請求給伺服器;

所以要進行3次握手

1、第一次揮手:客戶端傳送乙個 fin 報文,報文中會指定乙個序列號。此時客戶端處於fin_wait1狀態。

2、第二次握手:服務端收到 fin 之後,會傳送 ack 報文,且把客戶端的序列號值 + 1 作為 ack 報文的序列號值,表明已經收到客戶端的報文了,此時服務端處於 close_wait狀態。

3、第三次揮手:如果服務端也想斷開連線了,和客戶端的第一次揮手一樣,發給 fin 報文,且指定乙個序列號。此時服務端處於 last_ack 的狀態。

4、第四次揮手:客戶端收到 fin 之後,一樣傳送乙個 ack 報文作為應答,且把服務端的序列號值 + 1 作為自己 ack 報文的序列號值,此時客戶端處於 time_wait 狀態。需要過一陣子以確保服務端收到自己的 ack 報文之後才會進入 closed 狀態

5、服務端收到 ack 報文之後,就處於關閉連線了,處於 closed 狀態。

這裡特別需要主要的就是time_wait這個狀態了,這個是面試的高頻考點,就是要理解,為什麼客戶端傳送 ack 之後不直接關閉,而是要等一陣子才關閉。這其中的原因就是,要確保伺服器是否已經收到了我們的 ack 報文,如果沒有收到的話,伺服器會重新發 fin 報文給客戶端,客戶端再次收到 ack 報文之後,就知道之前的 ack 報文丟失了,然後再次傳送 ack 報文。

至於 time_wait 持續的時間至少是乙個報文的來回時間。一般會設定乙個計時,如果過了這個計時沒有再次收到 fin 報文,則代表對方成功就是 ack 報文,此時處於 closed 狀態。

TCP三次握手 四次揮手(面試)

第一次握手 客戶端傳送第乙個包,其中syn標誌位為1,ack 0,傳送順序號sequence x 隨機int 客戶端進入syn傳送狀態,等待伺服器確認。第二次握手 伺服器收到這個包後傳送第二個包,其中包syn ack標誌位為1,傳送順序號seq y 隨機int 接收順序號ack x 1,此時伺服器進...

面試常問的三次握手四次揮手

三次握手 第一次握手 client向server傳送連線請求 標誌位syn 1 並產生乙個隨機數 seq j 並將該資料報傳送給server,client進入傳送 syn sent 狀態,等待server確認。第二次握手 server收到資料報後由標誌位syn 1知道client請求建立連線,ser...

詳解TCP三次握手四次揮手面試題

tcp transmission control protocol 傳輸控制協議。是面向連線的 全雙工的協議。主要用來傳輸tcp報文的。而傳輸需要客戶端client與伺服器server建立連線來完成 三次握手 傳輸完成後需要釋放鏈結 四次揮手 建立連線 三次握手 第一次握手 首先客戶a主動開啟連線,...