自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

被印證的感覺,真爽!

網(wǎng)絡(luò) 無線技術(shù)
有位讀者在工作中抓到跟這個面試題場景類似的抓包圖,我看了下,現(xiàn)象跟我之前啃 TCP 源碼得出的結(jié)論是符合的。這種被印證的感覺真爽!

大家好,我是小林。

之前我在公眾號解答了一位讀者面試騰訊的面試題,問題如下:

針對這個問題,我也沒辦法用實驗來驗證我的結(jié)論,所以當(dāng)時結(jié)論是基于啃 TCP 源碼得出來的。

但是,就在昨天!

有位讀者在工作中抓到跟這個面試題場景類似的抓包圖,我看了下,現(xiàn)象跟我之前啃 TCP 源碼得出的結(jié)論是符合的。

這種被印證的感覺真爽!

我覺得這個案例還是挺有意思的,因為很好的說明是 TCP 傳輸協(xié)議是按序接收的。

所以,先來回顧騰訊一面的這個問題,再來看看跟這個問題相似的抓包圖。

回顧問題

這道鵝廠的網(wǎng)絡(luò)題可能是提問的讀者表述有問題。

因為如果 FIN 報文比數(shù)據(jù)包先抵達客戶端,此時 FIN 報文其實是一個亂序的報文,此時客戶端的 TCP 連接并不會從 FIN_WAIT_2 狀態(tài)轉(zhuǎn)換到 TIME_WAIT 狀態(tài)。

因此,我們要關(guān)注到點是看「在 FIN_WAIT_2 狀態(tài)下,是如何處理收到的亂序的 FIN 報文,然后 TCP 連接又是什么時候才進入到 TIME_WAIT 狀態(tài)?」。

我這里先直接說結(jié)論:

在 FIN_WAIT_2 狀態(tài)時,如果收到亂序的 FIN 報文,那么就被會加入到內(nèi)核中的「亂序隊列」,并不會進入到 TIME_WAIT 狀態(tài)。

等再次收到前面被網(wǎng)絡(luò)延遲的數(shù)據(jù)包時,會判斷亂序隊列有沒有數(shù)據(jù),然后會檢測亂序隊列中是否有可用的數(shù)據(jù),如果能在亂序隊列中找到與當(dāng)前報文的序列號保持的順序的報文,就會看該報文是否有 FIN 標(biāo)志,如果發(fā)現(xiàn)有 FIN 標(biāo)志,這時才會進入 TIME_WAIT 狀態(tài)。

我也畫了一張圖,大家可以結(jié)合著圖來理解。

神一般的抓包圖

下圖是昨天一位讀者發(fā)給我的抓包圖,圖中的異常情況,跟前面這個問題的現(xiàn)象有點類似:

你可能會有疑問為什么 TCP 握手時,雙方的 seq 都是 0 開始的?這個是抓包圖做了優(yōu)化,顯示的是相對值,而不是真實值,顯示相對值方便分析。

為了方便文字描述,我針對異常部分的報文進行編號如下:

圖中端口號為 11710 的為客戶端,端口號為 8080 的為服務(wù)端。另外,編號 4 是客戶端發(fā)送的 http 請求,抓包圖沒有顯示 TCP 信息,這里文字補充下:編號 4 數(shù)據(jù)報文 seq = 1,ack = 1,len = 27。

編號 6 是 FIN 報文,也就是服務(wù)端向客戶端發(fā)送的 FIN 報文(第一次揮手),但是是一個亂序的 FIN 報文,因為從編號 4 報文中的 ack = 1 知道,客戶端期望下一次收到的報文的序列號為 1,而當(dāng)前收到的 FIN 報文的 seq = 177,這并不是客戶端下一次期望收到的報文,所以是亂序的。

客戶端收到亂序 FIN 報文后,并不會從 establish 轉(zhuǎn)為 close_wait 狀態(tài),而是把這個亂序的 FIN 報文放到內(nèi)核中的亂序隊列。因為如果這時候就進入了 close_wait 狀態(tài),就會馬上發(fā)送 FIN 報文了(第三次揮手),而不會有客戶端后面發(fā)送的編號 8 和 9 報文的事情了。

編號 8 是應(yīng)答報文,是客戶端對編號 6 亂序 FIN 報文的應(yīng)答報文,可以看到這個應(yīng)答報文中 seq = 28,ack=1,因為并不是我期望的下一個報文,所以應(yīng)答報文中 ack 還是為 1。

編號 7 是數(shù)據(jù)報文,也就是服務(wù)端向客戶端發(fā)送的數(shù)據(jù)報文,該報文 seq = 1,ack=28,len=176,因為 seq 為 1,所以是客戶端期望收到的報文??蛻舳耸盏皆搱笪暮?,就回了編號 9 應(yīng)答報文,此應(yīng)答報文 seq = 28,ack = 178,其中 ack = 178 是告訴服務(wù)端:“你發(fā)的 seq = 178 之前(不包括seq=178)的報文,我都收到了,我下次期望收到的報文的 seq 為 178”。

客戶端收到編號 7 數(shù)據(jù)報文時還會做一件事情,會檢測「亂序隊列」中是否有可用的數(shù)據(jù),如果能在亂序隊列中找到與當(dāng)前收到報文的序列號「保持的順序」的報文,就把處于亂序隊列的報文移到可以被正常處理的數(shù)據(jù)隊列。比如,這次的案例中,編號 7 報文 seq = 1,len=176 的數(shù)據(jù)范圍是 1~176,而亂序隊列中的 FIN 報文的 seq = 177,這兩個報文的 seq 正好是保持順序的,所以會把 FIN 報文從亂序隊列中拿出來一起處理,然后發(fā)現(xiàn)有 FIN 標(biāo)志,于是就會轉(zhuǎn)換狀態(tài)。

所以,客戶端在應(yīng)答完編號 7 數(shù)據(jù)報文后,就立馬發(fā)送 FIN 報文了(第三次揮手),接著服務(wù)端應(yīng)答了該報文,至此四次揮手結(jié)束。

這個抓包圖跟前面這個騰訊的面試題有一點差異,差異在于:

  • 騰訊的面試題是在 FIN_WAIT_2 狀態(tài)下收到亂序的 FIN 報文(第三次揮手);
  • 抓包圖是在 establish 狀態(tài)收到了亂序的 FIN 報文(第一次揮手);

上面這兩種 TCP 狀態(tài),收到亂序的 FIN 報文,并不會立即轉(zhuǎn)換狀態(tài),只會被內(nèi)核放到一個亂序隊列里。等收到一個序列號符合「接收方」期望收到的序列號的數(shù)據(jù)包時,會檢測「亂序隊列」中是否有可用的數(shù)據(jù),如果能在亂序隊列中找到與當(dāng)前收到報文的序列號「保持的順序」的報文,就會看該報文是否有 FIN 標(biāo)志,如果發(fā)現(xiàn)有 FIN 標(biāo)志,就會轉(zhuǎn)換狀態(tài)。

所以,從這里可以看到, TCP 傳輸協(xié)議是按序接收,如果收到一個亂序的報文時,并且在接收窗口范圍內(nèi)(序列號超過接收窗口范圍外的報文就會被丟棄),就會緩存在內(nèi)核中的亂序隊列,不做其他處理。等收到能與亂序隊列中報文的序列號保持順序的報文,才會一起被處理。

TCP 層必須保證收到的字節(jié)數(shù)據(jù)是完整且有序的,所以如果序列號較低的 TCP 報文在網(wǎng)絡(luò)傳輸中丟失了,即使序列號較高的 TCP 報文已經(jīng)被接收了,應(yīng)用層也無法從內(nèi)核中讀取到這部分?jǐn)?shù)據(jù)。

舉個例子,如下圖:

圖中發(fā)送方發(fā)送了很多個 packet,每個 packet 都有自己的序號,你可以認(rèn)為是 TCP 的序列號,其中 packet 3 在網(wǎng)絡(luò)中丟失了,即使 packet 4-6 被接收方收到后,由于內(nèi)核中的 TCP 數(shù)據(jù)不是連續(xù)的,于是接收方的應(yīng)用層就無法從內(nèi)核中讀取到,只有等到 packet 3 重傳后,接收方的應(yīng)用層才可以從內(nèi)核中讀取到數(shù)據(jù)。

責(zé)任編輯:趙寧寧 來源: 小林coding
相關(guān)推薦

2020-05-06 11:00:11

git命令GitHub

2021-06-01 09:29:43

ArthasJVM內(nèi)存

2023-07-04 07:08:27

內(nèi)存游戲容量

2020-02-26 17:32:57

WindowsWindows 10操作系統(tǒng)

2009-05-31 08:31:06

PalmWebOS移動OS

2009-05-12 16:11:00

求職面試招聘

2022-08-01 10:01:11

JavaScript語言代碼庫

2022-10-26 13:00:00

2013-04-15 09:52:13

程序員

2021-08-07 07:48:28

JDKjava JDK17

2023-03-21 08:10:18

2023-03-29 09:00:00

2010-01-04 14:37:46

Linux Ubunt

2013-12-12 16:28:04

Lua腳本語言

2023-02-22 17:56:55

MySQL數(shù)據(jù)存儲

2021-07-19 09:42:45

Spring Boot@ValueJava

2024-09-09 00:00:06

Windows工具箱網(wǎng)站

2020-11-23 11:30:00

IDEA技巧開發(fā)

2014-06-12 11:20:23

Windows 9

2022-11-03 10:34:58

智能建筑物聯(lián)網(wǎng)能源管理
點贊
收藏

51CTO技術(shù)棧公眾號