前言
作為一名前端開發人員,我們最主要的日常工作之一就是與網路打交道。眾所周知,瀏覽器獲取一個頁面資源依託於HTTP協議。當我們想瀏覽器的位址列中輸入一段url時,瀏覽器會首先通過訪問DNS伺服器獲得url域名所對應的ip地址,然後將http報文傳送給ip所在的伺服器。伺服器接收報文後作出響應,將請求的資源傳送給瀏覽器。
以上過程看起來非常直觀且容易理解,然而這個過程只是真正的網路傳輸過程的一個抽象。實際上,HTTP協議得以準確無誤的傳送和接受資料,依託於其下面的TCP/IP協議族以及更底層(物理層)的種種協議。通過大致瞭解TCP/IP協議族的規則和特性,可以為我們理解HTTP協議以及處理網路傳輸過程中發生的種種問題提供非常大的幫助。本文就將通過一名前端的視角,帶領大家瞭解一些TCP/IP協議族的基本知識。
正文
TCP/IP協議族是什麼
我們知道,在網路的世界中,資料之間的主要在計算機之間進行傳遞。然而,這些計算機卻由各種不同的廠商生產,型號各異,甚至執行著完全不同的作業系統。那麼是什麼促使這些形態各異的計算機彼此連線,相互通訊呢?答案就是依靠TCP/IP協議族。
TCP/IP為什麼被稱為協議族呢?原因在於它不僅僅是單個協議,而是一組不同層次上的多個協議的組合。
四層模型
網路協議通常分不同層次進行開發,每一層分別負責不同的通訊功能。傳統上,我們將網路分為七層,即著名的OSI七層模型。這樣做的好處是顯而易見的,通過將一個複雜的流程,分化為一些功能獨立的子程式,可以有效的降低複雜度。同時使流程更加清晰,出現問題也可以更加快速的定位。
在TCP/IP協議族中,將協議系統劃分為四層,每一層負責不同的功能:
-
資料鏈路層:有時也被成為鏈路層或者網路介面層,一般包括計算機中的網路卡以及對用的驅動程式。資料鏈路層主要負責處理從電纜,網線等傳輸媒介傳遞過來的訊號,將其轉化為對應的二進位制資料。
-
網路層:網路層也被成為網際網路層。這一層中主要負責管理資料分組在網路中的活動,例如資料分組傳輸的選路。在TCP/IP協議族中,網路層主要包括IP協議(網際協議),ICMP協議(Internet網際網路控制報文協議)以及IGMP協議(Internet組管理協議)。
-
傳輸層:傳輸層中主要負責為計算機中的應用程式提供端到端的通訊。這一層的主要協議是TCP協議和UDP協議。這兩個協議互不相同:TCP協議的特點是高可靠性,他負責把應用程式交給它的資料分成合適的大小的資料塊,然後交給下面的網路層或者反過來將網路層傳過來的資料塊拆解成適合應用程式使用的資料段傳遞給應用程式。TCP擁有非常完備的校驗,分發,重傳等確保資料傳輸可靠的手段,因此應用層可以無需考慮這些細節。而另一方面,UDP則是更注重傳輸效率的協議,它為應用程式提供快速簡單的端到端的資料分組傳輸,而不確保這些資料能否真正的道道另一端。這兩種協議各有優缺點,下面的內容會再次介紹。
-
應用層:應用層可以簡單理解為中計算機應用程式,我們日常接觸的HTTP,FTP等協議就是這一層的協議。
當我們日常通過瀏覽器傳送一條http請求的時候,http報文即從我們計算機的應用層開始向下傳遞,每經過一層,該層對應的協議就會在上層傳來資料的基礎上新增一個首部,這個首部中包含了該層協議所管理的一些資訊。通過這種方式將資料層層打包最後經由資料鏈路層交給最下面的物理層傳遞出去,這些資料在網際網路中經過數臺路由器或其他代理伺服器等裝置,最終交給目標計算機。目標計算機得到資料後層層向上傳遞,每一層會將該層對應協議負責的首部摘除後再傳給上層。最後抵達應用層對應的某個應用程式。
雖然實際的過程中充滿了各種其他細節和問題,不過網際網路一份資料的傳輸過程大體就是如上面所說的這樣一個過程。
上面的這個過程可以用一張圖來展示:
下面我們就依據一份資料在各層中傳遞時的形式來逐個詳細分析這四層每一層的特點
資料鏈路層
資料鏈路層位於TCP/IP四層模型的最底端,位於OSI七層模型的第二層。
資料結構
在這一層中,上層傳來的資料經過協議處理後的一份資料,我們稱之為一幀(Frame),下面一張圖展示了鏈路層中一幀資料的格式
目的地址與源地址
在鏈路層中的地址指的的是計算機中網路卡的硬體地址,即mac地址。我們知道,每一個網路卡在出廠時,其內部都存有一個全世界獨一無二的硬體標識,稱為mac地址,它是的長度為6個位元組。在網路中,兩個計算機之間的通訊實際上就是計算機中的兩張網路卡之間的通訊。如果沒有mac地址,就無法得知通訊的具體位置,因此獲取mac地址是計算機通訊的基礎保障。
但是實際上,計算機程式在傳送連線請求時,一般只知道目的主機的IP地址,那麼mac地址是如何獲取的呢?這就要靠ARP協議來實現。
ARP協議(地址解析協議)可以看做是鏈路層的一個協議,它的作用是為IP地址與對應的mac地址之間提供動態的對映,這個過程是自動完成的,因此無需使用者或管理員關心。ARP協議將IP對映為mac地址的過程大致如下:
如果目的主機與源主機位於同一網段,那麼ARP協議會向本網段傳送一個廣播,網段中的所有主機都會受到一條訊息,這條訊息詢問哪臺主機的IP地址與目的主機地址相同。當目的主機接受到這條訊息,就做出應答,將自己的mac地址傳送過去。其他主機則將這條訊息忽略。
如果目的主機與源主機位於不同網段,那麼ARP協議會將訊息傳送給本地的路由,路由經過IP定址找到目的主機所在網段的路由,再由目的路由將訊息廣播出去,獲得目的主機響應後再返回給源主機。
一般來說, 每臺機器都維護的有一個ARP快取表, 儲存了近期的IP地址和硬體地址的對映關係, 可以用 arp -a
命令來檢視快取表中內容。
型別
型別欄位通過一個2位元組的資料來標識上層使用的協議,鏈路層通過這個欄位來執行不同的操作,通常的型別有:TCP,ARP,RARP(逆地址解析協議)。
資料
幀中的資料即是上層傳來的資料本身,資料的大小存在一個範圍,其上限是由MTU(最大傳輸單元)所決定的。圖中資料的大小範圍為46到1500位元組,1500這個上限是乙太網標準所規定的MTU。實際上資料鏈路層支援著數種不同的傳輸標準,如乙太網,IEEE 802.3,換回介面等不同標準下MTU的大小不盡相同,如IEEE 802.3規定MTU大小為1492。由於超出MTU的資料將被拋棄,因此如何處理MTU就至關重要。我們知道資料在傳送到目的主機所在網路前將會經由數個路由轉發,那麼傳送前就要確定的本地MTU應以兩臺通訊主機路徑中的最小MTU為依據。
CRC
CRC是資料的校驗碼, 又稱為校驗和,這是根據資料內容通過演算法生成的一個摘要,確保資料傳輸正確。
注意:上面這個資料格式是乙太網標準下的資料封裝格式,實際上鍊路層同時著支援多種標準,在這些標準下資料的封裝格式不盡相同,不過由於篇幅有限,這裡不再做展開。
網路層
網路層位於鏈路層的上方,在這一層中,主要由TCP/IP協議族最為核心的協議:IP協議來處理和傳輸資料。IP協議是一種不可靠,無連線的資料傳輸服務。所謂不可靠,意思是IP協議不能保證資料能夠成功到達目的地,IP協議提供最好的傳輸服務,但是如果傳輸過程中發生錯誤,資料丟失,IP協議將傳送一個訊息給上層,因此可靠性需要由上層來實現。而無連線的意思是IP協議不會為何任何關於資料的狀態資訊。對於IP協議來說,資料之間都是獨立的,前後兩個資料的接受和傳送順序可能會改變。
資料格式
和資料鏈路層一樣,由IP協議處理過的資料擁有自己的名字:IP資料包,讓我們從下圖來了解一下IP資料包的格式:
從圖中可以看出,一個IP資料包由首部和資料組成。資料即上層傳來的資料本體,而首部則是由IP協議新增的,通常長度為20個位元組。這裡主要介紹IP首部的各個欄位含義。
協議版本
一個4位二進位制數的標識,用來標識IP協議的版本,目前大部分的協議版本號為4,因此IP有時也稱為IPv4。目前另一種新的版本正在逐步被推廣,即IPv6。IPv6主要解決IPv4地址不足的問題,關於IP地址的問題會在下面介紹。
首部長度
首部長度指的是IP的首部佔32位的數目。前面說IP資料包首部一般為20位元組,但如果首部存在選項,那麼首部長度可能會超過20位元組。由於首部長度欄位是一個4位的二進位制數,因此首部的長度最長為60的位元組。
TOS服務型別
服務型別長度為8位。其中3位位優先權子欄位,這個欄位現在已經被忽略了;4位用來標識TOS子欄位;剩下的1位是未用欄位,必須置為0。
TOS子欄位的4位分別標識:最小時延、最大吞吐量、最高可靠性和最小費用。這4位中只能選擇1位設為1.如果4位都為0,那麼IP協議將選擇預設的一般服務。值得注意的是,現在大多數的TCP/IP實現都不支援TOS的這些特性,因此關於這些欄位的詳細內容請參考官方文件,這裡不做詳細介紹。
總長度
一個16位的二進位制數表示的是整個IP資料包的長度,它的單位是位元組。利用首部長度和總長度欄位,就可以算出資料包中資料部分的其實位置和長度,它是首部中必不可少的內容。原因在於網路層下面的資料鏈路層存在著最小的資料大小限制,如乙太網中為46位元組。但是IP資料包的大小可能小於這一數字,因此鏈路層會對不足部分進行填充。而如果沒有總長度欄位,接受方的IP層就無法得知46位元組中有多少是實際的資料。
總長度欄位為16位,意味著整個資料包大小可達65535位元組,然而實際上大多數鏈路層會將它進行切分,即分片處理。同時,上層的TCP協議和主機不能接受超過576位元組資料包等限制,IP資料包的長度通常無法達到65535位元組這一上限。
標識、標誌和片偏移
標識欄位是主機傳送的 每一份資料包的唯一標識,通常沒法送一份報文,它的值就會加1。它與標誌和片偏移欄位用來實現資料包分片技術。IP分片是將一份資料分割成多份資料包的一種技術,本文不做詳細介紹。
TTL
TTL(time-to-live)是指一份資料包的生存時間,它表示資料包最多可以經過多少個路由器。TTL的初始值由源主機設定,一但經過一個處理它的路由器,TTL的值就減去1,當這個欄位的值為0時,這份資料包就會被丟棄,併傳送訊息通知源主機。
協議
協議欄位用來標識是哪個協議像IP傳送資料,根據上層使用協議的不同,IP處理資料包的行為也不同。
首部校驗和
校驗和是根據IP首部計算出的一個值,它不對首部後面的資料進行計算。接收方在接收到資料包後同樣對首部求值,一旦計算結果與校驗和不符,那麼IP將丟棄這個資料包。指的注意的是IP不會傳送錯誤報文,而是交給上層去發現丟失了資料包並進行重傳。
源地址與目標地址
即IP地址,他們是一個32位的值。為了便於檢視,通常IP地址會以每8位轉成一個10進位制的數字的方式變為4個10進位制數,並且4個數字之間用 .
來劃分。這種表示方法稱為點分十進位制。
一個IP地址分為網路位和主機位,網路為用來劃分不同的網路,主機位用來區分網路中的特定的某一主機。根據網路位的長度,IP地址被劃分為5類:A、B、C、D、E。
-
A類IP地址: 一個A類IP地址由1位元組的網路地址和3位元組主機地址組成,網路地址的最高位必須是“0”, 地址範圍從1.0.0.0 到126.0.0.0。可用的A類網路有126個,每個網路能容納1億多個主機。
-
B類IP地址: 一個B類IP地址由2個位元組的網路地址和2個位元組的主機地址組成,網路地址的最高位必須是“10”,地址範圍從128.0.0.0到191.255.255.255。可用的B類網路有16382個,每個網路能容納6萬多個主機 。
-
C類IP地址: 一個C類IP地址由3位元組的網路地址和1位元組的主機地址組成,網路地址的最高位必須是“110”。範圍從192.0.0.0到223.255.255.255。C類網路可達209萬餘個,每個網路能容納254個主機。
上面三類IP地址是主要IP地址,其中存在一些特殊地址如:全零(“0.0.0.0”)地址對應於當前主機。全“1”的IP地址(“255.255.255.255”)是當前子網的廣播地址。
同時在IP地址3種主要型別裡,各保留了3個區域作為私有地址,其地址範圍如下: A類地址:10.0.0.0~10.255.255.255 B類地址:172.16.0.0~172.31.255.255 C類地址:192.168.0.0~192.168.255.255。這三種地址是一個網段內部使用,通常無法與公共IP進行通訊。
至於D類地址和E類地址。但這兩類地址用途比較特殊,在這裡只是簡單介紹一下:D類地址稱為廣播地址,供特殊協議向選定的節點傳送資訊時用。E類地址保留給將來使用。
除了以上的IP分類外,網路之間彼此劃分還有賴於另一個概念:子網掩碼。
簡單來說,一個子網掩碼用來標識一個IP地址中的網路位的長度。一個子網掩碼也是32個二進位制位,其對應IP的網路部分用1表示,對應IP地址的主機部分用0表示。將一個IP地址和子網掩碼做邏輯與運算就可得到這個IP地址得到網路位。而網路位不同即表示兩臺主機位於不同的網路之中。
綜上所述,一個完整的IP地址通常由IP加子網掩碼組成。
網路層中最重要的協議就是IP協議,而IP協議又是TCP/IP協議族的核心內容,本文礙於篇幅所限,很多關於IP協議的詳細內容如IP選址等都沒有介紹,感興趣的朋友建議閱讀相關文件和書籍來進一步瞭解。
傳輸層
傳輸層中主要有TCP和UDP兩種協議。本文著重講解TCP協議的相關特性。
TCP協議即傳輸控制協議,它為應用程式提供端到端的連線服務,是一種面向連線的,可靠的位元組流服務。面向連線意味著,兩個使用TCP的應用,在交換資料之前必須先建立一個TCP連線。如同打電話,首先要撥號,然後等待對方響應後才能彼此交流。可靠性是指TCP協議擁有數種保證資料切實被另一方接受的方法。
資料格式
TCP協議負責接收從應用層傳來的資料,它不對其內容最任何解釋(意味著TCP無法得知傳輸的資料是二進位制資料還是ascii字元),直接將資料新增上TCP首部,成為一個TCP報文段。一個TCP報文段的結構如下圖所示:
從圖中可以看出,一個TCP資料段的首部如果不計任選欄位,其大小通常為20個位元組。下面我們來逐一分析首部的欄位:
源埠號和目標埠號
每隔TCP資料段都包含這兩個欄位,用於尋找傳送和接收端應用程式的程式。這兩個值加上IP首部中的IP地址即可確定一個唯一的TCP連線。一個埠號的的長度為16位,這就是為什麼計算機中的埠號最多為65535的原因。在這寫埠中,存在這一些私有埠,即被計算機或一些應用程式保留的埠,如80埠用於HTTP協議,21埠用於FTP協議等。
序號與確認序號
序號(SYN)是一個32位的數值,用來標識從TCP傳送端想TCP接收端傳送的資料,它表示在這個報文段中的資料的位元組長度。這個欄位的值是累計的,下一次傳送的資料段的序號總為上一個資料段的序號加當前資料段資料的位元組長度。
與序號相對,確認序號(ASK)表示接受方所收到的下一個序號的初始值,因此確認序號是上次已經成功收到的資料段序號加1,只有ACK標誌(下面會提到)被設為1時,確認序號欄位才有效。
通過序號與確認序號可以保證傳送端傳送的每一條資料包都被接收端成功接收,如果中間丟失了一些檔案,那麼兩者就無法匹配,傳送端就會重新傳送從丟失處開始的所有資料。
首部長度
同IP資料包一樣,這個欄位表示首部長度為多少個32位。由於TCP首部存在可選欄位,因此這個欄位必須存在。
保留位
保留位是個6位的標識,通過把其中的一位設為1可以表示6中不同的含義:
- URG:使緊急指標有效。
- ACK:使確認序號有效。
- PSH:接收方應儘快將這個報文段交給應用層。
- RST:重建連線。
- SYN:用來表示發起連線。
- FIN:用來表示結束請求結束連線。
視窗大小
這一欄位用來進行TCP傳輸的流量控制,這個大小的單位位元組數,表示接收端期望接受的位元組。它的長度為16位,即最大65535位元組。通過首部選項改變視窗刻度,這個值可以按比例擴大,這一技術成為滑動視窗。相關知識這裡不做詳解。
校驗和
同樣如同上文,校驗和用於驗證資料是否改變,這是一個強制性的欄位,由傳送端進行計算和儲存,由接收端進行驗證。
緊急指標
只有URG標誌位1的時候這個欄位才有效。它使一端可以告訴另一端有些具有某種方式的“緊急資料”存放於普通的資料流中,這個欄位的值是一個正的偏移量,通過與首部的序號相加即可得出緊急資料的最後一個位元組的序號。它的具體使用方法這裡就不做介紹。
TCP連線的建立與斷開
由於TCP是一種面向連線的協議,在兩端間傳輸資料之前要先建立一個虛擬的連線。相信對TCP有過了解的朋友都聽說過所謂“三次握手”、“四次揮手”,它描述了TCP連線之前,傳送端與接受段需要進行的三次資訊傳遞以及連線斷開之前要做的4次資訊傳遞。這兩個個過程可以通過下圖來簡單展示:
三次握手的過程可以簡單描述如下:
- 第一次握手主機A通過一個標識為SYN標識位的資料段傳送給主機B請求連線,通過該資料段告訴主機B希望建立連線,需要B應答,並告訴主機B傳輸的起始序列號。
- 第二次握手是主機B用一個確認應答ACK和同步序列號SYNC標誌位的資料段來響應主機A,一是傳送ACK告訴主機A收到了資料段,二是通知主機A從哪個序列號做標記。
- 第三次握手是主機A確認收到了主機B的資料段並可以開始傳輸實際資料。
四次揮手的過程可以簡單描述如下:
- 主機A傳送FIN控制位發出斷開連線的請求。
- 主機B進行響應,確認收到斷開連線請求。
- 主機B提出反方向的關閉要求。
- 主機A確認收到的主機B的關閉連線請求。
實際上這兩個過程中存在著一些比較複雜的特殊情況和狀態轉移,礙於篇幅所限,這裡就不過多介紹了。
應用層
作為前端而言,我們最熟悉也是使用最多的應用層協議就是HTTP協議,HTTP協議又叫超文字傳輸協議,它的請求傳送和接受相應依靠的基礎便是以上幾層中的協議。由於HTTP協議內容複雜,同時它是我們前端開發者所必須詳細掌握的內容,這篇文章就不做過多敘述。有時間我會單獨再開一篇文章來詳細解析HTTP協議的種種內容和特性,敬請期待!
尾聲
這篇文章從頭至尾主要是介紹了一份資料,在不同的網路層,不同的協議中所對應的不同形式。通過了解這些資料形式,可以使我們對每一層中的主要特性有一個大致的瞭解。如文章開頭所言,作為一名前端開發者,瞭解這些知識可能不會對你實際編寫程式碼有什麼幫助,但是卻可以讓我們在網路傳輸出現問題的時候快速定位其出錯位置,幫助後端開發人員解決相關的問題,從而提升我們在團隊中的價值。然而另一方面,因為我們的目的並不是要成為一名網路通訊專家,因此這篇文章基本是一種走馬觀花式的介紹,很多深入且重要的內容通通一筆帶過了。對此有興趣有志向的朋友可以通過閱讀書籍等相關資料來加深對這些知識的理解。
最後還是老規矩,這篇文章期望用最易理解的方式和語言帶大家瞭解TCP/IP協議族的相關內容,但由於作者自己水平有限,文章中難免出現疏漏。如果您發現了文章中的一些問題,歡迎在留言中提出,我會盡量回復這些評論,及時把錯誤更正。
參考與引用
TCP/IP協議知識科普 《TCP/IP 協議詳解 卷一:協議》