-
1 # Python之王
-
2 # 雲渺書齋
三次握手
三次握手及建立TCP連線,建立一個TCP連線時,需要客戶端和服務端總共傳送3個包以確認連線的建立,這一過程有客戶端執行connect來觸發,流程如下:
圖 1 三次握手原理圖
握手之前主動開啟連線的客戶端結束Closed階段,被動開啟的伺服器端也結束Closed階段,並進入Listen階段,隨後開始三次握手。
1) 第一次握手,客戶端傳送syn包(SYN=1,seq=n)到伺服器端,此時客戶端進入SYN_SENT狀態,等待伺服器端確認。第一個syn包:SYN=1,seq=n,n為隨機數。
2) 第二次握手,伺服器端接收到syn包,結束Listen階段,並返回一個syn包(SYN=1,ACK=1,seq=k,ack=n+1),此時伺服器端進入SYN_RCVD階段,等待客戶端確認。第二個syn包:SYN=1,ACK=1,seq=k,ack=n+1,k為隨機數。
3) 第三次握手,客戶端接收到來自伺服器端的syn包,明確了資料傳輸是正常的,結束SYN_SENT階段,並向伺服器端返回一個syn包,客戶端進入Established階段。第三個syn包:ACK=1,seq=n+1,ack=k+1。
伺服器端接收到來自客戶端的確認之後,明確了資料傳輸是正常的,結束SYN_RCVD階段,進入Established階段。
在客戶端與伺服器端傳輸的syn包中,雙方的確認號ack和序號seq的值,都是在彼此ack和seq值的基礎上進行計算的,這樣做保證了TCP報文傳輸的連貫性。一旦出現某一方發出的syn包丟失,便無法繼續"握手",以此確保了"三次握手"的順利完成。
此後客戶端和伺服器端進行正常的資料傳輸。這就是"三次握手"的過程。
四次揮手四次揮手及釋放或解除TCP連線,連線的釋放必須是一方主動釋放,另一方被動釋放。流程如下:
圖 1 四次揮手原理圖
1) 第一次揮手,客戶端發出連線釋放syn包(FIN=1,seq=u)到伺服器端,並且停止再發送資料,主動關閉連線,進入FIN-WAIT-1狀態,等待伺服器端確認。
2) 第二次揮手,伺服器端收到客戶端傳送的連線釋放syn包後,即發出確認syn包(ACK=1,seq=v,ack=u+1)到客戶端,進入CLOSE-WAIT狀態,此時TCP處於半關閉狀態。客戶端收到伺服器端確認後,進入FIN-WAIT-2狀態,等待伺服器端發出的連線釋放syn包。
3) 第三次揮手,當伺服器端資料傳送完畢後,伺服器端傳送連線釋放syn包(FIN=1,ACK=1,seq=w,ack=u+1),伺服器端計入LAST-ACK狀態,等待客戶端最後確認。
4) 第四次揮手,當客戶端收到伺服器端連線釋放syn包後,客戶端發出確認syn包(ACK=1,seq=u+1,ack=w+1),客戶端進入TIME-WAIT狀態。此時TCP未釋放,需要經過時間等待計時器設定的時間2MSL後,客戶端才進入CLOSED狀態。
5) 伺服器端只要收到客戶端發出的確認,立即進入CLOSED狀態,由此完成四次揮手。
常見面試題問題1:如果已經建立了連線,但是客戶端突然出現了故障,怎麼辦?
TCP設有一個計時器,客戶端如果出現故障,伺服器端不能一直等待下去,白白浪費資源。伺服器端每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設定為2小時,若兩小時還沒有收到客戶端的任何資料,伺服器端就會發送一個探測包,以後每隔75秒鐘傳送一次。若一連發送10個探測包仍然沒反應,伺服器端就認為客戶端出了故障,接著就關閉連線。
問題2:為什麼要使用次握手建立連線?
客戶端發出去的第一個連線請求由於某些原因在網路節點中滯留了導致延遲,直到連線釋放的某個時間點才到達伺服器端,這是一個早已失效的報文,但是此時伺服器端仍然認為這是客戶端建立的連線請求,第一次握手。於是伺服器端迴應了客戶端,第二次握手。如果只有兩次握手,那麼到這裡,連線就建立了,但是此時客戶端並沒有任何資料要傳送,而伺服器端還處於等待中,造成很大的資源浪費。所以需要第三次握手,只有客戶端再次迴應一下,就可以避免這種情況。
問題3:什麼是TCP半連線?
在三次握手過程中,伺服器端傳送SYN、ACK後,收到客戶端的ACK之前的TCP連線稱為半連線,此時伺服器端處於SYN_RCVD狀態,當收到ACK之後,伺服器端進入Established狀態。
問題4:什麼是SYN攻擊?
SYN攻擊就是客戶端在短時間內偽造大量的源IP地址,分別向伺服器端傳送大量的SYN包,此時伺服器端會返回SYN/ACK包,因為源地址是偽造的,所以偽造的IP並不會應答,伺服器端沒有收到偽造的IP的迴應,重試3-5次並且等待一個SYN time,如果超時則丟棄這個連線。攻擊者大量傳送這種偽造源地址SYN請求,伺服器會消耗非常多的資源來處理這種半連線,同時還要不斷地對這些IP進行SYN+ACK重試。最終伺服器無暇理睬正常的連線請求,導致拒絕服務。
問題5:怎麼檢測SYN攻擊?
使用命令netstat -nap | grep SYN_RECV
問題6:為什麼"握手"是三次,"揮手"卻要四次?
TCP建立連線時之所以只需要"三次握手",是因為在第二次"握手"過程中,伺服器端傳送給客戶端的TCP報文是以SYN與ACK作為標誌位的。SYN是請求連線標誌,表示伺服器端同意建立連線;ACK是確認報文,表示告訴客戶端,伺服器端收到了它的請求報文。即SYN建立連線報文與ACK確認接收報文是在同一次"握手"當中傳輸的,所以"三次握手"不多也不少,正好讓雙方明確彼此資訊互通。
TCP釋放連線時之所以需要"四次揮手",是因為FIN釋放連線報文與ACK確認接收報文是分別由第二次和第三次"握手"傳輸的。釋放連線時,被動方伺服器,突然收到主動方客戶端釋放連線的請求時並不能立即釋放連線,因為還有必要的資料需要處理,所以伺服器先返回ACK確認收到報文,經過CLOSE-WAIT階段準備好釋放連線之後,才能返回FIN釋放連線報文。
問題7:為什麼客戶端在TIME-WAIT階段要等待2MSL?
客戶端發出最後的ACK確認報文時,並不能確定伺服器端能夠收到該段報文。所以客戶端在傳送完ACK確認報文之後,會設定一個時長為2MSL的計時器。MSL指的是Maximum Segment Lifetime:一段TCP報文在傳輸過程中的最大生命週期。2MSL即是伺服器端發出為FIN報文和客戶端發出的ACK確認報文所能保持有效的最大時長。伺服器端在1MSL內沒有收到客戶端發出的ACK確認報文,就會再次向客戶端發出FIN報文;如果客戶端在2MSL內,再次收到了來自伺服器端的FIN報文,說明伺服器端由於各種原因沒有接收到客戶端發出的ACK確認報文。客戶端再次向伺服器端發出ACK確認報文,計時器重置,重新開始2MSL的計時;否則客戶端在2MSL內沒有再次收到來自伺服器端的FIN報文,說明伺服器端正常接收了ACK確認報文,客戶端可以進入CLOSED階段,完成"四次揮手"。
所以,客戶端要經歷時長為2SML的TIME-WAIT階段;這也是為什麼客戶端比伺服器端晚進入CLOSED階段的原因。
詳情參考
三次握手:https://www.toutiao.com/i6827692110498497032/
四次揮手:https://www.toutiao.com/i6827639144907276813/
正春華枝俏,待秋實果茂,與君共勉。
-
3 # 小鳥攻城獅
面試官期望的
做為在大廠拿到《認證面試官》的我來說,我更期望能看到面試者的答案是:
三次握手原理,四次揮手原理
過程解讀,說不清楚,請在面試官前畫圖
舉例子
why,為什麼不是四次握手,三次揮手;為什麼甚至需要握手? 為什麼訊息不能與第一個資料包一起傳送?
發散思維,安全方面考慮。
比較兩點是後面的,或者說抓包軟體名稱,分析過之類的。
有朋友也才加過谷歌的面試,公司也出過這樣的題目:tcp 3 way handshake and setting the FIN bit?當然答案也因人而異。可參考
三次握手主要用於建立TCP套接字連線。 它的工作原理是:
客戶端節點透過IP網路將SYN資料包傳送到同一網路或外部網路上的伺服器。 這個資料包的目的是詢問/推斷伺服器是否能開啟新的連線。
目標伺服器必須具有可以接受和啟動新連線的開放埠。 當伺服器從客戶端節點收到SYN資料包時,它會響應並返回一個確認收據 - ACK資料包或SYN / ACK資料包。
客戶端節點從伺服器接收SYN / ACK並用ACK資料包進行響應。
完成此過程後,將建立連線並且主機和伺服器可以進行通訊。最好還畫一個圖:(English better!,發散到why,security better)
-
4 # 大學的那些事情
用簡單的例子比喻三次握手:甲乙兩人對話,
甲:我說的話能聽見嗎?(第一次握手)
乙:你說的話我能聽見,我說的話你能聽見嗎?(第二次握手)
甲:你說的話我也能聽見。(第三次握手)
三次握手成功後即開始資料接收和傳送。
再用個簡單的例子說一下四次揮手:
甲:我們分手吧!
乙:亞美得!
甲:堅決分手!
乙:好吧!祝你幸福!
這就是四次揮手,然而在抓包的時候發現,三次握手每次都是有的,而四次揮手有的時候只有三次,當乙方資料傳輸完畢,甲發出fin訊號的時候,乙就會斷開連線,甲再發個ack確認號即可完成四次揮手
在面試中,計算機網路的TCP三次握手和四次揮手是很常見的問題,但是在實際面試中,面試官會更願意聽到怎樣的回答?詳細程度是怎樣的?
回覆列表
TCP Connection
客戶端與伺服器之間資料的傳送和返回的過程當中需要建立一個叫 TCP Connection 的東西。
由於 TCP 不存在連線的概念,只存在請求和響應,請求和響應都是資料包,它們之間都是經過由 TCP 建立的一個從客戶端發起,伺服器接收的類似連線的通道,這個連線可以一直保持,HTTP 請求是在這個連線的基礎上傳送的。
在一個 TCP 連線上是可以傳送多個 HTTP 請求的,不同的版本這個模式不一樣。
在 HTTP/1.0 中這個 TCP 連線是在 HTTP 請求建立的時候同步建立的,HTTP 請求傳送到伺服器端,伺服器端響應了之後,這個 TCP 連線就關閉了。
HTTP/1.1 中可以以某種方式宣告這個連線一直保持,一個請求傳輸完之後,另一個請求可以接著傳輸。
這樣的好處是:在建立一個 TCP 連線的過程中需要“三次握手”的消耗,“三次握手”代表有三次網路傳輸。
如果 TCP 連線保持,第二個請求傳送就沒有這“三次握手”的消耗。HTTP/2 中同一個 TCP 連線裡還可以併發地傳輸 HTTP 請求。
TCP 報文格式簡介其中比較重要的欄位有:
序號(sequence number):Seq 序號,佔 32 位,用來標識從 TCP 源端向目的端傳送的位元組流,發起方傳送資料時對此進行標記。確認號(acknowledgement number):Ack 序號,佔 32 位,只有 ACK 標誌位為 1 時,確認序號欄位才有效,Ack=Seq+1。標誌位(Flags):共 6 個,即 URG、ACK、PSH、RST、SYN、FIN 等。六個標誌位具體含義如下:
URG:緊急指標(urgent pointer)有效。ACK:確認序號有效。PSH:接收方應該儘快將這個報文交給應用層。RST:重置連線。SYN:發起一個新連線。FIN:釋放一個連線。需要注意的是:
不要將確認序號 Ack 與標誌位中的 ACK 搞混了。確認方 Ack=發起方 Seq+1,兩端配對。TCP 的三次握手“三次握手”的詳解
所謂的三次握手即 TCP 連線的建立。這個連線必須是一方主動開啟,另一方被動開啟的。
以下為客戶端主動發起連線的圖解:
握手之前主動開啟連線的客戶端結束 CLOSED 階段,被動開啟的伺服器端也結束 CLOSED 階段,並進入 LISTEN 階段,隨後開始“三次握手”。
①首先客戶端向伺服器端傳送一段 TCP 報文。
其中:標記位為 SYN,表示“請求建立新連線”;序號為 Seq=x(x 一般為 1);隨後客戶端進入 SYN-SENT 階段。
②伺服器端接收到來自客戶端的 TCP 報文之後,結束 LISTEN 階段。並返回一段 TCP 報文。
其中:標誌位為 SYN 和 ACK,表示“確認客戶端的報文 Seq 序號有效,伺服器能正常接收客戶端傳送的資料,並同意建立新連線”(即告訴客戶端,伺服器收到了你的資料)。
序號為 Seq=y;確認號為 Ack=x+1,表示收到客戶端的序號 Seq 並將其值加 1 作為自己確認號 Ack 的值;隨後伺服器端進入 SYN-RCVD 階段。
其中:標誌位為 ACK,表示“確認收到伺服器端同意連線的訊號”(即告訴伺服器,我知道你收到我發的資料了)。
序號為 Seq=x+1,表示收到伺服器端的確認號 Ack,並將其值作為自己的序號值。
確認號為 Ack=y+1,表示收到伺服器端序號 Seq,並將其值加 1 作為自己的確認號 Ack 的值;隨後客戶端進入 ESTABLISHED 階段。
伺服器收到來自客戶端的“確認收到伺服器資料”的 TCP 報文之後,明確了從伺服器到客戶端的資料傳輸是正常的。結束 SYN-SENT 階段,進入 ESTABLISHED 階段。
在客戶端與伺服器端傳輸的 TCP 報文中,雙方的確認號 Ack 和序號 Seq 的值,都是在彼此 Ack 和 Seq 值的基礎上進行計算的,這樣做保證了 TCP 報文傳輸的連貫性。
一旦出現某一方發出的 TCP 報文丟失,便無法繼續"握手",以此確保了"三次握手"的順利完成。
此後客戶端和伺服器端進行正常的資料傳輸。這就是“三次握手”的過程。
“三次握手”的動態過程
“三次握手”的通俗理解
舉個栗子:把客戶端比作男孩,伺服器比作女孩。
用他們的交往來說明“三次握手”過程:
男孩喜歡女孩,於是寫了一封信告訴女孩:我愛你,請和我交往吧!;寫完信之後,男孩焦急地等待,因為不知道信能否順利傳達給女孩。女孩收到男孩的情書後,心花怒放,原來我們是兩情相悅呀!於是給男孩寫了一封回信:我收到你的情書了,也明白了你的心意,其實,我也喜歡你!我願意和你交往!寫完信之後,女孩也焦急地等待,因為不知道回信能否能順利傳達給男孩。男孩收到回信之後很開心,因為發出的情書女孩收到了,並且從回信中知道了女孩喜歡自己,並且願意和自己交往。然後男孩又寫了一封信告訴女孩:你的心意和信我都收到了,謝謝你,還有我愛你!女孩收到男孩的回信之後,也很開心,因為發出的情書男孩收到了。由此男孩女孩雙方都知道了彼此的心意,之後就快樂地交流起來了~~
這就是通俗版的“三次握手”,期間一共往來了三封信也就是“三次握手”,以此確認兩個方向上的資料傳輸通道是否正常。
為什麼要進行第三次握手為了防止伺服器端開啟一些無用的連線增加伺服器開銷以及防止已失效的連線請求報文段突然又傳送到了服務端,因而產生錯誤。
由於網路傳輸是有延時的(要透過網路光纖和各種中間代理伺服器),在傳輸的過程中,比如客戶端發起了 SYN=1 建立連線的請求(第一次握手)。
如果伺服器端就直接建立了這個連線並返回包含 SYN、ACK 和 Seq 等內容的資料包給客戶端,這個資料包因為網路傳輸的原因丟失了,丟失之後客戶端就一直沒有接收到伺服器返回的資料包。
客戶端可能設定了一個超時時間,時間到了就關閉了連線建立的請求。
再重新發出建立連線的請求,而伺服器端是不知道的,如果沒有第三次握手告訴伺服器端客戶端收的到伺服器端傳輸的資料的話,伺服器端是不知道客戶端有沒有接收到伺服器端返回的資訊的。
這個過程可理解為:
這樣沒有給伺服器端一個建立還是關閉連線埠的請求,伺服器端的埠就一直開著,等到客戶端因超時重新發出請求時,伺服器就會重新開啟一個埠連線。
那麼伺服器端上沒有接收到請求資料的上一個埠就一直開著,長此以往,這樣的埠多了,就會造成伺服器端開銷的嚴重浪費。
還有一種情況是已經失效的客戶端發出的請求資訊,由於某種原因傳輸到了伺服器端,伺服器端以為是客戶端發出的有效請求,接收後產生錯誤。
所以我們需要“第三次握手”來確認這個過程,讓客戶端和伺服器端能夠及時地察覺到因為網路等一些問題導致的連線建立失敗,這樣伺服器端的埠就可以關閉了,不用一直等待。
也可以這樣理解:“第三次握手”是客戶端向伺服器端傳送資料,這個資料就是要告訴伺服器,客戶端有沒有收到伺服器“第二次握手”時傳過去的資料。
若傳送的這個資料是“收到了”的資訊,接收後伺服器就正常建立 TCP 連線,否則建立 TCP 連線失敗,伺服器關閉連線埠。由此減少伺服器開銷和接收到失效請求發生的錯誤。
抓包驗證下面是用抓包工具抓到的一些資料包,可用來分析 TCP 的三次握手:
圖中顯示的就是完整的 TCP 連線的”三次握手”過程。在 52528→80 中,52528 是本地(客戶端)埠,80 是伺服器的埠。80 埠和 52528 埠之間的三次來回就是"三次握手"過程。
注意到“第一次握手”客戶端傳送的 TCP 報文中以[SYN]作為標誌位,並且客戶端序號 Seq=0。
接下來”第二次握手”伺服器返回的 TCP 報文中以[SYN,ACK]作為標誌位;並且伺服器端序號 Seq=0;確認號 Ack=1(“第一次握手”中客戶端序號 Seq 的值+1)。
最後”第三次握手”客戶端再向伺服器端傳送的 TCP 報文中以[ACK]作為標誌位;其中客戶端序號 Seq=1(“第二次握手”中伺服器端確認號 Ack 的值);確認號 Ack=1(“第二次握手”中伺服器端序號 Seq 的值 +1)。
這就完成了”三次握手”的過程,符合前面分析的結果。
TCP 的四次揮手對於"三次握手"我們耳熟能詳,因為其相對的簡單。但是,我們卻不常聽見“四次揮手”,就算聽過也未必能詳細地說明白它的具體過程。下面就為大家詳盡,直觀,完整地介紹“四次揮手”的過程。
“四次揮手”的詳解
所謂的四次揮手即 TCP 連線的釋放(解除)。連線的釋放必須是一方主動釋放,另一方被動釋放。
以下為客戶端主動發起釋放連線的圖解:
揮手之前主動釋放連線的客戶端結束 ESTABLISHED 階段。隨後開始“四次揮手”。
①首先客戶端想要釋放連線,向伺服器端傳送一段 TCP 報文。
其中:標記位為 FIN,表示“請求釋放連線“;序號為 Seq=U。
隨後客戶端進入 FIN-WAIT-1 階段,即半關閉階段。並且停止在客戶端到伺服器端方向上傳送資料,但是客戶端仍然能接收從伺服器端傳輸過來的資料。
注意:這裡不傳送的是正常連線時傳輸的資料(非確認報文),而不是一切資料,所以客戶端仍然能傳送 ACK 確認報文。
②伺服器端接收到從客戶端發出的 TCP 報文之後,確認了客戶端想要釋放連線,隨後伺服器端結束 ESTABLISHED 階段,進入 CLOSE-WAIT 階段(半關閉狀態)並返回一段 TCP 報文。
其中:標記位為 ACK,表示“接收到客戶端傳送的釋放連線的請求”。
序號為 Seq=V,確認號為 Ack=U+1,表示是在收到客戶端報文的基礎上,將其序號 Seq 值加 1 作為本段報文確認號 Ack 的值;隨後伺服器端開始準備釋放伺服器端到客戶端方向上的連線。
客戶端收到從伺服器端發出的 TCP 報文之後,確認了伺服器收到了客戶端發出的釋放連線請求,隨後客戶端結束 FIN-WAIT-1 階段,進入 FIN-WAIT-2 階段。
前"兩次揮手"既讓伺服器端知道了客戶端想要釋放連線,也讓客戶端知道了伺服器端了解了自己想要釋放連線的請求。於是,可以確認關閉客戶端到伺服器端方向上的連線了。
其中:標記位為 FIN,ACK,表示“已經準備好釋放連線了”。注意:這裡的 ACK 並不是確認收到伺服器端報文的確認報文。
序號為 Seq=W,確認號為 Ack=U+1,表示是在收到客戶端報文的基礎上,將其序號 Seq 值加 1 作為本段報文確認號 Ack 的值。
隨後伺服器端結束 CLOSE-WAIT 階段,進入 LAST-ACK 階段。並且停止在伺服器端到客戶端的方向上傳送資料,但是伺服器端仍然能夠接收從客戶端傳輸過來的資料。
④客戶端收到從伺服器端發出的 TCP 報文,確認了伺服器端已做好釋放連線的準備,結束 FIN-WAIT-2 階段,進入 TIME-WAIT 階段,並向伺服器端傳送一段報文。
其中:標記位為 ACK,表示“接收到伺服器準備好釋放連線的訊號”。
序號為 Seq=u+1;表示是在收到了伺服器端報文的基礎上,將其確認號 Ack 值作為本段報文序號的值。
確認號為 Ack=w+1;表示是在收到了伺服器端報文的基礎上,將其序號 Seq 值作為本段報文確認號的值。隨後客戶端開始在 TIME-WAIT 階段等待 2MSL。
伺服器端收到從客戶端發出的 TCP 報文之後結束 LAST-ACK 階段,進入 CLOSED 階段。由此正式確認關閉伺服器端到客戶端方向上的連線。
客戶端等待完 2MSL 之後,結束 TIME-WAIT 階段,進入 CLOSED 階段,由此完成“四次揮手”。
後“兩次揮手”既讓客戶端知道了伺服器端準備好釋放連線了,也讓伺服器端知道了客戶端了解了自己準備好釋放連線了。
於是,可以確認關閉伺服器端到客戶端方向上的連線了,由此完成“四次揮手”。
與“三次揮手”一樣,在客戶端與伺服器端傳輸的 TCP 報文中,雙方的確認號 Ack 和序號 Seq 的值,都是在彼此 Ack 和 Seq 值的基礎上進行計算的。
這樣保證了 TCP 報文傳輸的連貫性,一旦出現某一方發出的 TCP 報文丟失,便無法繼續"揮手",以此確保了"四次揮手"的順利完成。
“四次揮手”的通俗理解舉個栗子:把客戶端比作男孩,伺服器比作女孩。
透過他們的分手來說明“四次揮手”過程:
"第一次揮手":日久見人心,男孩發現女孩變成了自己討厭的樣子,忍無可忍,於是決定分手,隨即寫了一封信告訴女孩。“第二次揮手”:女孩收到信之後,知道了男孩要和自己分手,怒火中燒,心中暗罵:你算什麼東西,當初你可不是這個樣子的!於是立馬給男孩寫了一封回信:分手就分手,給我點時間,我要把你的東西整理好,全部還給你!男孩收到女孩的第一封信之後,明白了女孩知道自己要和她分手。隨後等待女孩把自己的東西收拾好。“第三次揮手”:過了幾天,女孩把男孩送的東西都整理好了,於是再次寫信給男孩:你的東西我整理好了,快把它們拿走,從此你我恩斷義絕!“第四次揮手”:男孩收到女孩第二封信之後,知道了女孩收拾好東西了,可以正式分手了,於是再次寫信告訴女孩:我知道了,這就去拿回來!這裡雙方都有各自的堅持:
女孩自發出第二封信開始,限定一天內收不到男孩回信,就會再發一封信催促男孩來取東西!男孩自發出第二封信開始,限定兩天內沒有再次收到女孩的信就認為,女孩收到了自己的第二封信;若兩天內再次收到女孩的來信,就認為自己的第二封信女孩沒收到,需要再寫一封信,再等兩天…..倘若雙方信都能正常收到,最少只用四封信就能徹底分手!這就是“四次揮手”。
為啥握手是三次,揮手卻要四次TCP 建立連線時之所以只需要"三次握手",是因為在第二次"握手"過程中,伺服器端傳送給客戶端的 TCP 報文是以 SYN 與 ACK 作為標誌位的。
SYN 是請求連線標誌,表示伺服器端同意建立連線;ACK 是確認報文,表示告訴客戶端,伺服器端收到了它的請求報文。
即 SYN 建立連線報文與 ACK 確認接收報文是在同一次"握手"當中傳輸的,所以"三次握手"不多也不少,正好讓雙方明確彼此資訊互通。
TCP 釋放連線時之所以需要“四次揮手”,是因為 FIN 釋放連線報文與 ACK 確認接收報文是分別由第二次和第三次"握手"傳輸的。
為何建立連線時一起傳輸,釋放連線時卻要分開傳輸?
建立連線時,被動方伺服器端結束 CLOSED 階段進入“握手”階段並不需要任何準備,可以直接返回 SYN 和 ACK 報文,開始建立連線。釋放連線時,被動方伺服器,突然收到主動方客戶端釋放連線的請求時並不能立即釋放連線。因為還有必要的資料需要處理,所以伺服器先返回 ACK 確認收到報文,經過 CLOSE-WAIT 階段準備好釋放連線之後,才能返回 FIN 釋放連線報文。所以是“三次握手”,“四次揮手”。