抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

目錄

  • 抓包過程
  • TCP 首部分析
  • TCP 三次牽手過程
  • TCP 四次分手過程
  • 常見面試經典問題為什麼牽手是三次,分手是四次?為什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?


過程

使用了 Wireshark 進行抓包,用兩個最常用的 curl 和 ping 命令來演示抓包情況,開啟抓包。

<code>## 先訪問我自己的網站首頁
curl https://zengzhiqin.kuaizhan.com
## 再查看我自己網站的地址
ping https://zengzhiqin.kuaizhan.com
/<code>

Wireshark根據 ping 命令得到的地址進行條件過濾,得到上面兩個命令所得到的包,主要有 TCP(https基於tcp協議)協議和 ICMP(ping命令是基於 ICMP 協議)協議的包,如下圖所示:

抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

抓包分析


TCP 首部分析

抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

TCP包首部內容一一對應


抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

TCP首部


首部內容簡單分析:

  1. 源端口目標端口

包通過傳輸層千辛萬苦找到了機器,機器那麼多應用,假如這個時候艾莉給洪世賢發微信撩sao,世賢開了 QQ 又開了微信,這個時候就靠端口號來區分不同服務,QQ和微信的端口號肯定不一樣,因此才能消息才能正確找到微信應用。

  1. 序列號和確認號

數據分段傳輸過程中,序列號可以保證所有傳輸的數據按照正常的次序進行重組,而且通過確認保證數據傳輸的完整性。

  • 如圖所示,整理分析五個連續的請求包數據的序列號和確認號進行序列號分析:

整理分析如下:

抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

序列號可以用來確定傳輸內容的位置,傳輸到哪一個字節了,接收端接收到好根據序列號進行重組數據。相對序列號和相對確認號是用來簡化隨機序列號和隨機確認號的。

下一個請求包的序列號 = 上一個請求包序列號 + 數據長度

  • 請求應答過程如下
抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

請求應答

確認號就是用來確認回覆哪個序列號的多大的數據包,所以Ack=請求包的Seq+數據長度 。並且通過確認序列號,確認號,數據長度的值,可以確定此數據包是否完整。

  1. 數據偏移

就是首部長度,因為首部除了 20 字節固定長度之外,還有選項部分,是可選可變長度,所以需要有個偏移量告訴數據首部長度位置。

  1. 保留

此 6 bit 二進制沒有用到

  1. 狀態位
抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

請求建立連接的數據包的狀態位


抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

狀態含義

小說明:大寫的表示狀態,如ACK,小寫的表示確認號,如Ack;

  1. 窗口

tcp是可靠傳輸,有接收緩存和發送緩存,緩存被叫做窗口,通過滑動窗口技術實現可靠傳輸(這個地方還挺複雜的,下一篇會寫關於可靠傳輸和擁塞控制相關的)

  1. 檢驗和

用來保證 TCP 頭和數據的內容在抵達目的時的正確性完整性

  1. 緊急指針

如果設置了 URG 位,這個域將被檢查作為額外的指令,告訴 CPU 從數據包的哪裡開始讀取數據,優先處理此包的命令。插隊打亂了原來的隊伍順序,把列寧同志的團隊人員單獨優先處理,需要記錄下這部分人的信息,是這個團隊的就先走。

  1. 選項

可以規定最大數據報的長度為多少,還可以支持選擇性的進行確認。

  1. 填充

選項和填充一共40個字節,如果不夠需要進行填充湊夠了

TCP 三次牽手過程

洪世賢飾客戶端,林品如飾服務端

抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

三次交涉牽手建立婚姻

牽手過程:

(客戶端)世賢:品如,你好美客戶端發起請求,頭部設置為SYN為1表示他要請求建立連接,並且發送一個隨機序列號x,此時世賢進入 SYN_SENT 求婚等待愛情狀態;

SYN包:SYN=1, ACK=0, Seq=x

(服務端)品如:世賢,你好帥服務端接收到連接請求,頭部設置SYN+ACK表示他要回應了,並且自己也隨機生成一個序列號標識自己y,通過將ack確認號設置為客戶端的請求序列號x +1 的方式來告訴請求的客戶端他回應的是哪個客戶端,因為可能有很多個客戶端同時向他請求建立連接,進行相應回應,此時品如進入了 SYN_RCVD 收到求婚並且同意等待下一步指示狀態

SYN+ACK包:SYN=1, ACK=1, Seq=y, Ack=x+1

(客戶端)世賢:品如,我們結婚客戶端接收到服務端回覆之後,再次確認連接,頭部設置為ACK表示他收到了服務端的確認請求現在進行確認,ACK為1表示他要進行確認了,ack=y+1=服務端的請求序列號+1,表示他確認的是服務端這個包的請求,seq=x+1因為上一個客戶端請求序列號是x,這個請求包從 x+1 開始,此時世賢收到同意回覆進入了宣佈結婚 ESTABILSHED 狀態, 品如收到了結婚請求也進入了結婚狀態

ACK包:ACK=1, Seq=x+1, Ack=y+1

小結:

因為建立連接之前是沒有數據傳輸的,但是 SYN,ACK 等狀態需要佔用一個序號,所以這個地方請求序列號加的數據都是1,建立連接之後有數據傳輸,序列號和確認號加的數據都會是數據的長度;

  • Ack=請求序列號+數據長度;
  • 包的序列號Seq = 同一端上一個包的序列號+數據長度;
  • 下一個包的Seq = 上一個應答包的Ack

漲姿勢:藉助wireshark的分析工具,點擊 wireshark 的 Statistic 下面的Follow Graph,能得到如下的分析圖,也可以很直觀的看到牽手分手以及序列號:

抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

tcp


TCP 四次分手過程

抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

四次分手過程的序列號和確認號,和上面牽手是一樣的分析,就不貼圖了貼個世賢。

抓包分析TCP首部,三次握手四次揮手過程,推導經典面試題

四次揮手過程

(客戶端)世賢:你不夠騷

(服務端)品如:我的衣櫃不好看嗎

(服務端)品如:算了衣服你們玩,我去跳海

(客戶端)世賢:你喜歡大海,我愛過你

這個分手過程讀者自己看圖吧,寫下來太多了,注意看雙方狀態,序列號和確認號。

常見面試經典問題

為什麼牽手是三次,分手是四次?

三次牽手原因:

一般如果客戶端給服務端發起一個請求,服務端回覆了,一來一回就能表示網絡是暢通的,可以發數據。那麼為什麼需要第三個數據包呢?

首先,客戶端請求建立連接如果沒有成功是會一直重試的,那麼就會有多個建立連接請求。


世賢和品如的故事

世賢飾客戶端A數據包,竊格瓦拉飾客戶端B數據包,品如飾服務端

  1. 假如世賢第一次求愛之前先繞遠路去美國買了束玫瑰花,然後 竊格瓦拉 從牢裡出來了直接就去找品如求愛了,品如這時候答應了竊格瓦拉的求愛,品如等著和竊格瓦拉來約她看海;
  2. 然後世賢也到了,品如一看世賢好帥反正她沒有結婚又答應了世賢的求愛,於是品如又等著世賢約她看海;
  3. 試想一下全世界男的都去找品如告白一次,那品如就有看不完的海了,主要原因是因為品如不知道哪一個男的是來真的。所以需要有人求婚,也就是第三次確認,結婚了就不用和別的男的看海了,直接放棄掉別人。

如果只有兩次,那麼服務端回應了就算是建立了連接,但是服務端沒法判斷他回應的請求連接是否在使用,這就會導致下面兩種情況:

  • 第一種是會造成很多無效連接資源不能釋放。請求包因為網絡慢耗時嚴重,客戶端重複發了很多包,一段時間後這些包到了服務端回覆建立起了很多不必要的連接,這些連接資源無法釋放,三次牽手第三次再次確認之後服務端建立連接並且將其他的無效連接釋放掉。
  • 第二種是確認包丟失造成循環死鎖問題,如下圖

四次分手原因

牽手容易分手難,都市的飲食男女應該都能感受到這點。

主要是因為服務端收到關閉請求之後,服務端的數據可能還沒有傳完,這個時候服務端會繼續把數據傳輸完,然後再告訴客戶端可以關閉了,客戶端再關閉。

為什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

MSL指一個片段在網絡中最大的存活時間,2MSL是兩倍的MSL(Maximum Segment Lifetime),就是一個發送和一個回覆所需的最大時間。

網絡是不可靠的,如果最後的ACK包丟失瞭然後客戶端又已經關閉了,那麼服務端還會一直髮送 FIN 請求關閉但是沒人理他,他就會一直髮FIN,那麼服務端就會一直持續發 FIN 從而沒法關閉了。所以客戶端需要再等2MSL,這段時間一來一回的路上再也沒有 FIN 包過來了,因此客戶端可以放心關閉了。

感覺自己在寫劇本,滿腦子都是品如的衣櫃,有收穫的老鐵點贊或者點在看來鼓勵一下作者吧,感謝觀看~

下期預告: tcp流量控制和擁塞控制的實現


分享到:


相關文章: