1. 網路TCP建立連接為什麼需要三次握手而結束要四次
一、TCP握手協議
在TCP/IP協議中,TCP協議提供可靠的連接服務,採用三次握手建立一個連接。
第一次握手:建立連接時,客戶端發送syn包(syn=j)到伺服器,並進入SYN_SEND狀態,等待伺服器確認;
第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;
第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手。
完成三次握手,客戶端與伺服器開始傳送數據,在上述過程中,還有一些重要的概念:
未連接隊列:在三次握手協議中,伺服器維護一個未連接隊列,該隊列為每個客戶端的SYN包(syn=j)開設一個條目,該條目表明伺服器已收到SYN包,並向客戶發出確認,正在等待客戶的確認包。這些條目所標識的連接在伺服器處於Syn_RECV狀態,當伺服器收到客戶的確認包時,刪除該條目,伺服器進入ESTABLISHED狀態。
Backlog參數:表示未連接隊列的最大容納數目。
SYN-ACK
重傳次數
伺服器發送完SYN-ACK包,如果未收到客戶確認包,伺服器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次重傳,如果重傳次數超過系統規定的最大重傳次數,系統將該連接信息從半連接隊列中刪除。注意,每次重傳等待的時間不一定相同。
半連接存活時間:是指半連接隊列的條目存活的最長時間,也即服務從收到SYN包到確認這個報文無效的最長時間,該時間值是所有重傳請求包的最長等待時間總和。有時我們也稱半連接存活時間為Timeout時間、SYN_RECV存活時間。
2. 6 張圖帶你搞懂 TCP 為什麼是三次握手,而不是兩次或四次
1三次握手
2兩次握手(情況1)
3兩次握手(情況2)
OK,下面正經地來回答下這個問題,要搞清楚這個問題,首先得了解TCP究竟是如何保證可靠傳輸的。
PS:TCP協議中,主動發起請求的一端稱為『客戶端』,被動連接的一端稱為『服務端』。不管是客戶端還是服務端,TCP連接建立完後都能發送和接收數據。
起初,伺服器和客戶端都為CLOSED狀態。在通信開始前,雙方都得創建各自的傳輸控制塊(TCB)。伺服器創建完TCB後便進入LISTEN狀態,此時准備接收客戶端發來的連接請求。
第一次握手
客戶端向服務端發送連接請求報文段。該報文段的頭部中SYN=1,ACK=0,seq=x。請求發送後,客戶端便進入SYN-SENT狀態。
第二次握手
服務端收到連接請求報文段後,如果同意連接,則會發送一個應答:SYN=1,ACK=1,seq=y,ack=x+1。該應答發送完成後便進入SYN-RCVD狀態。
第三次握手
當客戶端收到連接同意的應答後,還要向服務端發送一個確認報文段,表示:服務端發來的連接同意應答已經成功收到。該報文段的頭部為:ACK=1,seq=x+1,ack=y+1。客戶端發完這個報文段後便進入ESTABLISHED狀態,服務端收到這個應答後也進入ESTABLISHED狀態,此時連接的建立完成!
防止失效的連接請求報文段被服務端接收,從而產生錯誤。
PS:失效的連接請求:若客戶端向服務端發送的連接請求丟失,客戶端等待應答超時後就會再次發送連接請求,此時,上一個連接請求就是『失效的』。
若建立連接只需兩次握手,客戶端並沒有太大的變化,仍然需要獲得服務端的應答後才進入ESTABLISHED狀態,而服務端在收到連接請求後就進入ESTABLISHED狀態。
此時如果網路擁塞,客戶端發送的連接請求遲遲到不了服務端,客戶端便超時重發請求,如果服務端正確接收並確認應答,雙方便開始通信,通信結束後釋放連接。此時,如果那個失效的連接請求抵達了服務端,由於只有兩次握手,服務端收到請求就會進入ESTABLISHED狀態,等待發送數據或主動發送數據。但此時的客戶端早已進入CLOSED狀態,服務端將會一直等待下去,這樣浪費服務端連接資源。
TCP連接的釋放一共需要四步,因此稱為『四次揮手』。
我們知道,TCP連接是雙向的,因此在四次揮手中,前兩次揮手用於斷開一個方向的連接,後兩次揮手用於斷開另一方向的連接。
第一次揮手
若A認為數據發送完成,則它需要向B發送連接釋放請求。該請求只有報文頭,頭中攜帶的主要參數為:FIN=1,seq=u。此時,A將進入FIN-WAIT-1狀態。
第二次揮手
B收到連接釋放請求後,會通知相應的應用程序,告訴它A向B這個方向的連接已經釋放。此時B進入CLOSE-WAIT狀態,並向A發送連接釋放的應答,其報文頭包含:ACK=1,seq=v,ack=u+1。
A收到該應答,進入FIN-WAIT-2狀態,等待B發送連接釋放請求。
第二次揮手完成後,A到B方向的連接已經釋放,B不會再接收數據,A也不會再發送數據。但B到A方向的連接仍然存在,B可以繼續向A發送數據。
第三次揮手
當B向A發完所有數據後,向A發送連接釋放請求,請求頭:FIN=1,ACK=1,seq=w,ack=u+1。B便進入LAST-ACK狀態。
第四次揮手
A收到釋放請求後,向B發送確認應答,此時A進入TIME-WAIT狀態。該狀態會持續2MSL時間,若該時間段內沒有B的重發請求的話,就進入CLOSED狀態,撤銷TCB。當B收到確認應答後,也便進入CLOSED狀態,撤銷TCB。
為了保證B能收到A的確認應答。若A發完確認應答後直接進入CLOSED狀態,那麼如果該應答丟失,B等待超時後就會重新發送連接釋放請求,但此時A已經關閉了,不會作出任何響應,因此B永遠無法正常關閉。
本文轉載自:「掘金」,原文:https://tinyurl.com/nrputn47,版權歸原作者所有。