TCP/IP 系列之 Header 篇

這是 TCP/IP 系列的第二篇,閱讀目標是建立對網絡包結構的初步認識。

上一篇里,我們提到一次完整的 TCP 會話其實是一個字節(jié)流,只不過我們可以按照一定的規(guī)則來切割這個字節(jié)流,從而劃分出一個個的網絡包。我們經常說抓包分析網絡故障,這個抓包里所指的包在不同的語境下其實意義并不相同,首先我們得對包的構成形成具象的認知。

再看七層協(xié)議

剛畢業(yè)那會,大家都喜歡在簡歷上寫「精通 TCP/IP 協(xié)議」,面試被問起時就必答三次握手和 OSI 七層模型,再多就說不出來了。問七層模型是什么就機械式的從上至下背誦一遍,這離精通還差了一本【TCP/IP 詳解】。

我在完整的學習過一遍網絡協(xié)議棧之后,深感所謂的七層模型是偏工業(yè)的說法,看到七層協(xié)議圖之后,其實很難明白這七層是如何一層層互相構成的,更符合大腦感官的是另一種認知形式,是一種洋蔥形的結構,層層疊疊互相包裹,可以用下圖表示:

左邊是教材上的結構,右邊是我所說的洋蔥式的結構。如果以一個 HTTP 請求為例,右圖中 Application 部分就代表我們用 Charles 抓包時所感知的部分,這一部分要最后轉化為光信號,在光纖中傳輸,還需要經過一層層的轉化,這個轉化過程說白了,就是在每一層加上一個 header。

  • Application 層(HTTP)的數據在經過傳輸層(TCP Layer)的時候,會加上 TCP 的 header,成為一個 TCP Segment。
  • 傳輸層(TCP)的 Segment 在經過網絡層(IP Layer)的時候,會加上 IP 的 header,成為一個 IP Packet。
  • 網絡層的 IP Packet 在經過鏈路層(Link Layer)的時候,會加上Link Layer 的 header,成為一個 Frame。
  • 最后 Frame 會在物理層,將數字信號轉化為物理信號傳輸。

這里值得特別注意的是,在每一層,有不同的英文術語來對應包的概念,比如在 TCP 層的包叫做 Segment,在 IP 層的叫做 Packet,在鏈路層的叫做 Frame,另外和 TCP 位于同一層的 UDP 包我們一般叫做 Datagram,不同協(xié)議層里術語并不一樣,好處是,在交流的時候,我們選擇不同的英文單詞就能預先確立是在那一層討論協(xié)議。而 Segment、Packet、Frame、Datagram 等翻譯成中文的時候,都是譯為「包」,大家說讀英文原版資料是不是更好,這些術語我們需要特別記憶,可以對照下圖:

 +-------------+-------------------------+
 | Application |  HTTP Packet            |
 +-------------+-------------------------+
 | Transport   |  TCP Segment            |
 +-------------+-------------------------+
 | Network     |  IP Packet              |
 +-------------+-------------------------+
 | Link        |  Frame                  | 
 +-------------+-------------------------+         光纖
 | Physical    |  Bits                   | ====================> 
 +-------------+-------------------------+

不過有些場景下,我們也會用 Packet 來泛指每一層的包,但是用每一層自己的術語會更準確和專業(yè),這些行話和習慣我們也需要了解。

我們可以用一個公式來表示每一層協(xié)議的構成:

Packet = Protocol Header + Payload

每一層的包都可以用這個公式來表示。Payload 指傳入這一層的數據內容,比如:

TCP Segment = TCP header + HTTP data

有了這個認知之后,對于每一層協(xié)議的學習,最后就落實到每一層 header 的學習上了,學習 TCP 就是研究 TCP header 的構成,header 里的每一個 bit 位都有特別的用處,來實現(xiàn)協(xié)議層對于網絡傳輸的控制。這也是為什么我經常會說,所謂的網絡協(xié)議學習就是 header 學習,這也是本文標題的含義所在。

深入 Header

【TCP/IP 詳解】大致有 1000 頁,通讀的過程會很漫長且枯燥,知道每一層協(xié)議都是關于 header 的設計之后,大家其實可以先跳躍式的閱讀,先學習感興趣的部分,有了收獲知識的正向反饋之后,在回過頭來填補更多的知識細節(jié)。比如大家一般都對 TCP 協(xié)議比較感興趣(確實也是最有意思的部分,后面的文章也重點分析),那么可以先跳到第十二章:

Chapter 12 TCP: The Transmission Control Protocol(Preliminaries)

或者第十三章,真正明白所謂的三次握手:

Chapter 13 TCP Connection Management

由于每一層的設計都是獨立的,所以先學習傳輸層并不會有什么障礙,這也是分層架構的意義所在,各層各司其職,互不依賴具體的實現(xiàn)。

我們的學習行為,大致上可以分為兩類,理解(理解思想)和記憶(強行記憶)。對于 header 的學習,除了理解 header 每個 bit 的意義之外,還需要一些記憶行為,對于一些關鍵信息的強制性記憶,有助于我們形成更深刻的認知。我們以 TCP 的 header 為例:

上圖是一個 TCP header,以下是一些需要「死記硬背」的信息點:

一個 TCP Header 一般有 20 個字節(jié),如果啟用了 options,header的長度可以達到 60 個字節(jié)。上圖中每一行是 4 個 bytes,32 個 bits。我先帶大家學習下前 5 行,每一行是 4 Bytes,五行剛好是 20 個 bytes。計算機世界中,通常會以 bit,byte,word(4 個 byte)等不同粒度來描述信息,header 的學習一般是以 4 個字節(jié)為一個單位來展示的。

  • 第一行,由 Source port 和 Destination port 構成,二者各占 2 個字節(jié),剛好一起占據第一行的 4 個字節(jié)。這兩個字段分別表示 TCP 連接中的,發(fā)送方端口號和接收方的端口號,既然一個 port 只占 2 個 bytes,那么端口值的范圍自然就是 0~65535 啦。
  • 第二行,Sequence number,表示發(fā)送方的序列號。這個序列號表示的是什么呢?一個 TCP 流是有無數個 0 和 1 構成,這些 0 和 1 以 8 個 bit 為單位,可以分割成一個個的 byte,TCP 是可靠傳輸協(xié)議,每一個 byte 都是有標號的,因為我們需要追蹤每個 byte 是否被成功傳輸了,每個 byte 的標號就是我們這里的 sequence number。假設我們建立 TCP 連接的時候,發(fā)一個 sync 包,我們就以 0 標記 sync 包的第一個字節(jié),那么 sync 包中的 Sequence 值就是 0。實際應用中,處于安全考慮,TCP 流的第一個 Sequence number 一般不會是 0,而是一個隨機數。Sequence number 占據 4 個字節(jié),也就是 2 的 32 次方,這個數字并不算大,每個包都會用掉一些,如果達到最大值之后,就取余從 0 重新開始。
  • 第三行,Acknowledge number,表示接收方 ack 的序列號。接收方收到發(fā)送方一個的 TCP 包之后,取出其中的 sequence number,在下一個接收方自己要發(fā)送的包中,設置 ack 比特位為 1,同時設置 acknowledge number 為 sequence number + 1。所以接收方的 acknowledge number 表示的是,接收方期待接收的下一個包起始字節(jié)的標號,大家可以仔細理解下這一句話。所以 acknowledge number 和 sequence number 是配對使用的。
  • 第四行,這一行尤其重要,出于篇幅的考慮,其中細節(jié)會在后續(xù)的文章中講解。這里簡單提下從 CWR 到 FIN 的 8 個 bit,這 8 個 bit 里每一位都是一個標記位,用來標記當前 TCP 包的特殊含義。比如我們所說的三次握手,第一個 sync 包,就是將 SYN 位置為 1。第二個 syn + ack 包就是將 header 的 ACK 和 SYN 位都置為 1。第三個 ack 包即將 ACK 位置 1。剩余的幾個 bit 位暫時不展開講了,大家可以自己看書先學習下。
  • 第五行,這一行只有兩個字段,即 Checksum 和 Urgent pointer。checksum 是個通用的計算機概念,做完整性校驗之用,在很多協(xié)議(IP,UDP,ICMP)中都有應用,這個值有包的發(fā)送方去計算,之后由包的接收方取出來校驗。Urgent pointer 為兩個字節(jié)的偏移量,加上當前包的 sequence number,用來標記某一個范圍內的 bytes 為特殊用途數據。

怎么樣、其實沒有多少信息量對不對?這么跟著理解一遍 header 中的每一個 bytes 之后,是不是加深了對 TCP 的理解呢?

同理,學習完 TCP 的 header 之后,大家可以再去把 IP 的 header,frame 的 header 都搜索出來,對照關鍵字段去理解學習,最后再配合【TCP/IP 詳解】一書閱讀效果更好。

Tcpdump 實戰(zhàn)

上面是理論部分,可能有些枯燥,大家可以在理解之后,使用 tcpdump 抓包實戰(zhàn)下,進一步加深理解。我們就來抓包,基于上面 tcp header 的學習,抓下三次握手的包 :)

我們可以用如下命令來抓三次握手的包:

sudo tcpdump -i en0 "tcp[tcpflags] & (tcp-syn|tcp-ack) != 0"

輸出結果為:

  • 18:18:45.687476 IP 192.168.3.7.65284 > 59.37.116.101.https: Flags [S], seq 3942311653, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 589105996 ecr 0,sackOK,eol], length 0
  • 18:18:45.719744 IP 59.37.116.101.https > 192.168.3.7.65284: Flags [S.], seq 303118583, ack 3942311654, win 14280, options [mss 1412,sackOK,TS val 1712930033 ecr 589105996,nop,wscale 8], length 0
  • 18:18:45.719986 IP 192.168.3.7.65284 > 59.37.116.101.https: Flags [.], ack 1, win 4112, options [nop,nop,TS val 589106029 ecr 1712930033], length 0

你能根據上面 tcp header 的學習,理解上面 tcpdump 命令的含義嗎?tcpflags 指的是 header 中的哪些位呢?

對于 tcpdump 的使用還不太了解的同學,可以翻閱我之前的一篇介紹文章。

當然 TCP 里還包含著很多有趣的知識點,大家可以先行閱讀,后面我會逐步講解,比如 TCP 的 ARQ 機制,F(xiàn)low Control 等。

總結

這次新啟的 TCP/IP 系列文章對我來說,會是一次耗時費力,曠日持久的旅途。希望能夠慢火細熬,徐徐烹制,將這道傾注心力、營養(yǎng)豐盛的網絡協(xié)議佳肴制作完成,與君共享。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容