關於TCP三次握手四次分手,以前看資料解釋的都很籠統,不少地方都不是很明白,因此很難記,前幾天看的一個博客豁然開朗,惋惜如今找不到了。如今把以前的疑惑總結起來,方便一下你們。網絡
網上好多都是錯的,只能本身畫了,一個正確的圖的確能夠方便理解。併發
SYN,ACK,FIN存放在TCP的標誌位,一共有6個字符,這裏就介紹這三個:
spa
SYN:表明請求建立鏈接,因此在三次握手中前兩次要SYN=1,表示這兩次用於創建鏈接,至於第三次什麼用,在疑問三裏解答。blog
FIN:表示請求關閉鏈接,在四次分手時,咱們發現FIN發了兩遍。這是由於TCP的鏈接是雙向的,因此一次FIN只能關閉一個方向。資源
ACK:表明確認接受,從上面能夠發現,不論是三次握手仍是四次分手,在迴應的時候都會加上ACK=1,表示消息接收到了,而且在創建鏈接之後的發送數據時,都需加上ACK=1,來表示數據接受成功。博客
seq:序列號,什麼意思呢?當發送一個數據時,數據是被拆成多個數據包來發送,序列號就是對每一個數據包進行編號,這樣接受方纔能對數據包進行再次拼接。請求
初始序列號是隨機生成的,這樣不同的數據拆包解包就不會鏈接錯了。(例如:兩個數據都被拆成1,2,3和一個數據是1,2,3一個是101,102,103,很明顯後者不會鏈接錯誤)im
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的變化,這纔是重點!
關於seq和ack關鍵字的解釋中已經說明了。
下面解釋明明兩次就能夠創建鏈接的爲何還要加第三次的確認。
若是發送兩次就能夠創建鏈接話,那麼只要客戶端發送一個鏈接請求,服務端接收到併發送了確認,就會創建一個鏈接。
可能出現的問題:若是一個鏈接請求在網絡中跑的慢,超時了,這時客戶端會從發請求,可是這個跑的慢的請求最後仍是跑到了,而後服務端就接收了兩個鏈接請求,而後所有迴應就會建立兩個鏈接,浪費資源!
若是加了第三次客戶端確認,客戶端在接受到一個服務端鏈接確認請求後,後面再接受到的鏈接確認請求就能夠拋棄無論了。
TCP是雙向的,因此須要在兩個方向分別關閉,每一個方向的關閉又須要請求和確認,因此一共就4次。
不知道你是否是感受到豁然開朗?反正我是明白了哈哈~ 若是以上心得有問題,歡迎下方留言。