關於TCP三次握手四次分手,之前看資料解釋的都很籠統,很多地方都不是很明白,所以很難記,前幾天看的一個博客豁然開朗,可惜現在找不到了。現在把之前的疑惑總結起來,方便一下大家。
(此文爲網上看到的很優秀的文章,在此總結整理,以供自己學習之用)
先上個TCP三次握手和四次分手的圖
網上好多都是錯的,一個正確的圖的確可以方便理解。
疑問一,上圖傳遞過程中出現的幾個字符(SYN,ACK,FIN,seq,ack)各代表什麼意思
SYN,ACK,FIN存放在TCP的標誌位,一共有6個字符,這裏就介紹這三個:
SYN:代表請求創建連接,所以在三次握手中前兩次要SYN=1,表示這兩次用於建立連接,至於第三次什麼用,在疑問三裏解答。
FIN:表示請求關閉連接,在四次分手時,我們發現FIN發了兩遍。這是因爲TCP的連接是雙向的,所以一次FIN只能關閉一個方向。
ACK:代表確認接受,從上面可以發現,不管是三次握手還是四次分手,在迴應的時候都會加上ACK=1,表示消息接收到了,並且在建立連接以後的發送數據時,都需加上ACK=1,來表示數據接收成功。
seq:序列號,什麼意思呢?當發送一個數據時,數據是被拆成多個數據包來發送,序列號就是對每個數據包進行編號,這樣接受方纔能對數據包進行再次拼接。
初始序列號是隨機生成的,這樣不一樣的數據拆包解包就不會連接錯了。(例如:兩個數據都被拆成1,2,3和一個數據是1,2,3一個是101,102,103,很明顯後者不會連接錯誤)
ack:這個代表下一個數據包的編號,這也就是爲什麼第二請求時,ack是seq+1,
(這裏要吐槽一下,當初不懂的時候查資料,發現好多地方把ACK和ack都搞混了,害的我被坑了好久...)
如果你仔細看了上面對每個字符的解釋,那麼相信我畫的三次握手和四次分手的圖你也就明白了。
再複習一遍
在創建連接時,
1.客戶端首先要SYN=1,表示要創建連接,
2.服務端接收到後,要告訴客戶端:我接受到了!所以加個ACK=1,就變成了ACK=1,SYN=1
3.理論上這時就創建連接成功了,但是要防止一個意外(見疑問三),所以客戶端要再發一個消息給服務端確認一下,這時只需要ACK=1就行了。
**三次握手完成!**
在四次分手時,
1.首先客戶端請求關閉客戶端到服務端方向的連接,這時客戶端就要發送一個FIN=1,表示要關閉一個方向的連接(見上面四次分手的圖)
2.服務端接收到後是需要確認一下的,所以返回了一個ACK=1
3.這時只關閉了一個方向,另一個方向也需要關閉,所以服務端也向客戶端發了一個FIN=1 ACK=1
4.客戶端接收到後發送ACK=1,表示接受成功
**四次分手完成!**
我爲什麼沒有在上面的過程中,加入seq和ack呢?就如我對這兩個關鍵字的解釋的一樣,這兩個是數據拆分和組裝必備元素,所以所有的請求都需要這兩個元素,只要明白了作用,就可以自己舉一反三。
關於握手和分手,主要還是SYN,FIN,ACK的變化,這纔是重點!
疑問二,每次發送請求時爲什麼ack要+1
關於seq和ack關鍵字的解釋中已經說明了。
疑問三,爲什麼需要三次握手
下面解釋明明兩次就可以建立連接的爲什麼還要加第三次的確認。
如果發送兩次就可以建立連接話,那麼只要客戶端發送一個連接請求,服務端接收到併發送了確認,就會建立一個連接。
可能出現的問題:如果一個連接請求在網絡中跑的慢,超時了,這時客戶端會從發請求,但是這個跑的慢的請求最後還是跑到了,然後服務端就接收了兩個連接請求,然後全部迴應就會創建兩個連接,浪費資源!
如果加了第三次客戶端確認,客戶端在接受到一個服務端連接確認請求後,後面再接收到的連接確認請求就可以拋棄不管了。
疑問四,爲什麼需要四次分手
TCP是雙向的,所以需要在兩個方向分別關閉,每個方向的關閉又需要請求和確認,所以一共就4次。