大連網(wǎng)站建設選網(wǎng)龍建網(wǎng)站
文章目錄
- 1、通俗語言理解
- 1.1 三次握手
- 1.2 四次揮手
- 2、進一步理解三次握手和四次揮手
- 2.1 三次握手
- 2.2 四次揮手
1、通俗語言理解
1.1 三次握手
C:客戶端 S:服務器端
第一次握手:
C:在嗎?我要和你建立連接。
第二次握手:
S:在的呢!來吧,確定要連接嗎?
第三次握手:
C:非常確定!咱們建立連接吧。
為什么要三次握手?好麻煩!兩次握手不就可以了嗎?我想知道為什么。
答:如果是;兩次握手,S告訴C你來吧,同時S就打開了一個連接,這個時候如果C已經(jīng)掛了,那S一直等C同時還開啟了一個連接。
就像你和你朋友約會,你給他準備了一個驚喜,但是他卻沒來。
1.2 四次揮手
C:客戶端 S:服務器端
第一次揮手:
C:我的數(shù)據(jù)已經(jīng)傳完了,我想和你斷開連接。
第二次揮手:
S:好的,我知道了,但是我這邊還有數(shù)據(jù)給你,你先不要和我斷開。
第三次揮手:
S:我的數(shù)據(jù)已經(jīng)傳送完了,你可以和我斷開連接了!
第四次揮手:
C:我已經(jīng)收到你的讓我斷開連接的信息了,可以斷開了。
為什么要四次揮手?好麻煩!三次揮手不就可以了嗎?我想知道為什么。
答:當S端收到斷開連接的信息時,S端可能還有數(shù)據(jù)要鄉(xiāng)C端發(fā)送,使用確認狀態(tài)(ACK)和結束狀態(tài)(FIN)要分開發(fā)送
2、進一步理解三次握手和四次揮手
2.1 三次握手
首先很多人會先講下握手的過程:
1、第一次握手:客戶端給服務器發(fā)送一個 SYN 報文。
2、第二次握手:服務器收到 SYN 報文之后,會應答一個 SYN+ACK 報文。
3、第三次握手:客戶端收到 SYN+ACK 報文之后,會回應一個 ACK 報文。
4、服務器收到 ACK 報文之后,三次握手建立完成。
作用是為了確認雙方的接收與發(fā)送能力是否正常。
這里解釋一下為啥只有三次握手才能確認雙方的接受與發(fā)送能力是否正常,而兩次卻不可以:
- 第一次握手:客戶端發(fā)送網(wǎng)絡包,服務端收到了。這樣服務端就能得出結論:客戶端的發(fā)送能力、服務端的接收能力是正常的。
- 第二次握手:服務端發(fā)包,客戶端收到了。這樣客戶端就能得出結論:服務端的接收、發(fā)送能力,客戶端的接收、發(fā)送能力是正常的。不過此時服務器并不能確認客戶端的接收能力是否正常。
- 第三次握手:客戶端發(fā)包,服務端收到了。這樣服務端就能得出結論:客戶端的接收、發(fā)送能力正常,服務器自己的發(fā)送、接收能力也正常。
因此,需要三次握手才能確認雙方的接收與發(fā)送能力是否正常。
這個過程的我們應該要描述的更詳細一點,因為三次握手的過程中,雙方是由很多狀態(tài)的改變的,而這些狀態(tài),也是面試官可能會問的點。所以我覺得在回答三次握手的時候,我們應該要描述的詳細一點,而且描述的詳細一點意味著可以扯久一點。加分的描述我覺得應該是這樣:
剛開始客戶端處于 closed 的狀態(tài),服務端處于 listen 狀態(tài)。然后
-
1、第一次握手:客戶端給服務端發(fā)一個 SYN 報文,并指明客戶端的初始化序列號 ISN(c)。此時客戶端處于 SYN_Send 狀態(tài)。
-
2、第二次握手:服務器收到客戶端的 SYN 報文之后,會以自己的 SYN 報文作為應答,并且也是指定了自己的初始化序列號 ISN(s),同時會把客戶端的 ISN + 1 作為 ACK 的值,表示自己已經(jīng)收到了客戶端的 SYN,此時服務器處于 SYN_REVD 的狀態(tài)。
-
3、第三次握手:客戶端收到 SYN 報文之后,會發(fā)送一個 ACK 報文,當然,也是一樣把服務器的 ISN + 1 作為 ACK 的值,表示已經(jīng)收到了服務端的 SYN 報文,此時客戶端處于 establised 狀態(tài)。
-
4、服務器收到 ACK 報文之后,也處于 establised 狀態(tài),此時,雙方以建立起了鏈接。
模型參考1
模型參考2
提示:
- (1) SYN=1 表示該報文不攜帶數(shù)據(jù),但消耗一個序號 seq=x,seq=x是客戶端的初始化序列號,因為tcp是面向字節(jié)流的
- (2) SYN=1 表示該報文不攜帶數(shù)據(jù),但消耗一個序號 seq=y,seq=y是服務器的初始化序列號,ACK=1是一個確認號
ack=x+1,表示服務器下次接收到的序號希望是x+1。然后服務器進入到SYN-RCVD等待的狀態(tài) - (3) ACK=1是一個確認號,seq=x+1是上一次服務器回應的序號要求,ack=y+1表示客戶下一次接收到的序號希望是y+1
2.2 四次揮手
-
1、第一次揮手:客戶端發(fā)送一個 FIN 報文,報文中會指定一個序列號。此時客戶端處于FIN_WAIT1狀態(tài)。
-
2、第二次握手:服務端收到 FIN 之后,會發(fā)送 ACK 報文,且把客戶端的序列號值 + 1 作為 ACK 報文的序列號值,表明已經(jīng)收到客戶端的報文了,此時服務端處于 CLOSE_WAIT狀態(tài)。
-
3、第三次揮手:如果服務端也想斷開連接了,和客戶端的第一次揮手一樣,發(fā)給 FIN 報文,且指定一個序列號。此時服務端處于 LAST_ACK 的狀態(tài)。
-
4、第四次揮手:客戶端收到 FIN 之后,一樣發(fā)送一個 ACK 報文作為應答,且把服務端的序列號值 + 1 作為自己 ACK 報文的序列號值,此時客戶端處于 TIME_WAIT 狀態(tài)。需要過一陣子以確保服務端收到自己的 ACK 報文之后才會進入 CLOSED 狀態(tài)
-
5、服務端收到 ACK 報文之后,就處于關閉連接了,處于 CLOSED 狀態(tài)。
模型參考1
模型參考2
這里特別需要主要的就是TIME_WAIT這個狀態(tài)了,這個是面試的高頻考點,就是要理解,為什么客戶端發(fā)送 ACK 之后不直接關閉,而是要等一陣子才關閉。這其中的原因就是,要確保服務器是否已經(jīng)收到了我們的 ACK 報文,如果沒有收到的話,服務器會重新發(fā) FIN 報文給客戶端,客戶端再次收到 ACK 報文之后,就知道之前的 ACK 報文丟失了,然后再次發(fā)送 ACK 報文。
至于 TIME_WAIT 持續(xù)的時間至少是一個報文的來回時間。一般會設置一個計時,如果過了這個計時沒有再次收到 FIN 報文,則代表對方成功就是 ACK 報文,此時處于 CLOSED 狀態(tài)。
參考資料:三次握手和四次揮手(面試必問)