面試官:你說一下TCP為什么需要三次握手和四次揮手?
TCP協(xié)議是一種面向連接的、可靠的、基于字節(jié)流的運輸層通信協(xié)議,TCP是全雙工模式,需要三次握手建立連接,四次揮手關(guān)閉連接。
三次握手
三次握手(Three-way Handshake)是指建立一個 TCP 連接時,需要客戶端和服務(wù)器總共發(fā)送3個報文。
三次握手的目的是連接服務(wù)器指定端口,建立 TCP 連接,并同步連接雙方的序列號和確認號,交換 TCP 窗口大小信息。在 socket 編程中,客戶端執(zhí)行 connect() 時。將觸發(fā)三次握手。 三次握手過程如下:
圖片
剛開始客戶段和服務(wù)器端都處于CLOSED(關(guān)閉)狀態(tài),隨后服務(wù)器進程處于LISTEN(收聽)狀態(tài),等待客戶端的連接請求。
- 第一次握手(發(fā)送SYN):客戶端向服務(wù)器發(fā)出連接請求,附帶客戶端序列號seq,然后進入 SYN_SENT(同步已發(fā)送) 狀態(tài),等待服務(wù)器的確認。
- 第二次握手(發(fā)送SYN+ACK):服務(wù)器收到連接請求,同意建立連接,然后向客戶段發(fā)送確認連接信息,附帶向客戶端連接請求,此時服務(wù)器進入 SYN_RCVD(同步收到) 狀態(tài)。
- 第三次握手(發(fā)送ACK):客戶端收到服務(wù)器的確認連接信息,向服務(wù)器發(fā)送確認連接,此時TCP連接已經(jīng)建立,客戶端進入 ESTABLISHED 狀態(tài)。當(dāng)服務(wù)器收到客戶端發(fā)送的確認報文后也會進入 ESTABLISHED 狀態(tài),完成三次握手。
為什么需要三次握手,而不是二次握手?三次握手的目的是為了防止已失效的連接請求突然又傳送到了服務(wù)端,而產(chǎn)生錯誤。
假設(shè)采用兩次握手建立連接,客戶端第一次向服務(wù)端發(fā)送建立連接請求,因為網(wǎng)絡(luò)延遲的原因,一直沒有到達服務(wù)器。于是客戶端再次向服務(wù)端重新發(fā)送建立連接請求,這次服務(wù)端收到連接請求后,向客戶端回復(fù)確認,建立連接。但是這時網(wǎng)絡(luò)延遲恢復(fù),服務(wù)端又收到客戶端第一次發(fā)送的連接請求,服務(wù)端認為客戶端又發(fā)起了一次連接,再次回復(fù)確認,又建立了一個連接。
服務(wù)端認為有兩個連接,客戶端認為有一個連接,造成數(shù)據(jù)狀態(tài)不一致。
至于為什么不像斷開連接一樣采用四次握手,因為服務(wù)端把確認連接請求和向客戶端發(fā)送的建立連接請求合并成一次請求,發(fā)送給客戶端了。
四次揮手
四次揮手是指斷開一個TCP連接時,需要客戶端和服務(wù)端總共發(fā)送4個報文以確認連接的斷開。 四次揮手的過程如下:
圖片
- 第一次揮手(發(fā)送FIN):當(dāng)通信的一方完成數(shù)據(jù)發(fā)送任務(wù),需要關(guān)閉連接時,它會發(fā)送一個FIN(結(jié)束)報文段,進入FIN_WAIT_1 狀態(tài)。無論是客戶端還是服務(wù)端,任何一方都可以主動發(fā)起關(guān)閉連接的請求。
- 第二次揮手(發(fā)送ACK):服務(wù)端收到FIN報文段后,發(fā)送一個ACK報文段作為回應(yīng),并進入CLOSE-WAIT狀態(tài)??蛻舳耸盏紸CK后,進入FIN-WAIT-2狀態(tài)。這時候已經(jīng)斷開了客戶端與服務(wù)端的連接,服務(wù)端依然可以繼續(xù)向客戶端發(fā)送數(shù)據(jù)。
- 第三次揮手(發(fā)送FIN):服務(wù)器端完成數(shù)據(jù)傳輸后,發(fā)送一個FIN報文段,請求關(guān)閉連接,進入LAST-ACK狀態(tài)。
- 第四次揮手(發(fā)送ACK):客戶端收到服務(wù)器的 FIN 包后,發(fā)送ACK報文段作為回應(yīng),并進入TIME-WAIT狀態(tài)。經(jīng)過 2MSL 后,客戶端才進入 CLOSED 狀態(tài)。服務(wù)器端收到客戶端的確認包 ACK 后進入CLOSED 狀態(tài),連接被最終關(guān)閉。
為什么需要四次揮手?
由于TCP連接是全雙工的,即數(shù)據(jù)可以在兩個方向上流動,因此每個方向都必須要單獨進行關(guān)閉,關(guān)閉一個方向上的連接需要一次請求和一次確認,最終需要四次請求。
為什么不能是三次,不能像建立連接那樣把第二次和第三次合并成一次?
因為在第二次請求時服務(wù)端向客戶端發(fā)送確認關(guān)閉連接,此時服務(wù)端可能還有一些數(shù)據(jù)沒有傳輸完成,需要繼續(xù)向客戶端發(fā)送數(shù)據(jù),不能跟合并服務(wù)器向客戶端發(fā)送的關(guān)閉連接請求,所以需要拆分成兩個連接請求。