TCP/IP 協定棧是一系列網絡協定的總和,是構成網絡通信的核心骨架,它定義了電子裝置如何連入網際網路,以及資料如何在它們之間進行傳輸。TCP/IP 協定采用4層結構,分别是應用層、傳輸層、網絡層和鍊路層,每一層都呼叫它的下一層所提供的協定來完成自己的需求。由于我們大部分時間都工作在應用層,下層的事情不用我們操心;其次網絡協定體系本身就很複雜龐大,入門門檻高,是以很難搞清楚TCP/IP的工作原理,通俗一點講就是,一個主機的資料要經過哪些過程才能發送到對方的主機上。 接下來,我們就來探索一下這個過程。

實體媒體就是把電腦連接配接起來的實體手段,常見的有光纖、雙絞線,以及無線電波,它決定了電信号(0和1)的傳輸方式,實體媒體的不同決定了電信号的傳輸帶寬、速率、傳輸距離以及抗幹擾性等等。
TCP/IP協定棧分為四層,每一層都由特定的協定與對方進行通信,而協定之間的通信最終都要轉化為 0 和 1 的電信号,通過實體媒體進行傳輸才能到達對方的電腦,是以實體媒體是網絡通信的基石。
下面我們通過一張圖先來大概了解一下TCP/IP協定的基本架構:
當通過http發起一個請求時,應用層、傳輸層、網絡層和鍊路層的相關協定依次對該請求進行包裝并攜帶對應的首部,最終在鍊路層生成以太網資料包,以太網資料包通過實體媒體傳輸給對方主機,對方接收到資料包以後,然後再一層一層采用對應的協定進行拆包,最後把應用層資料交給應用程式處理。
網絡通信就好比送快遞,商品外面的一層層包裹就是各種協定,協定包含了商品資訊、收貨位址、收件人、聯系方式等,然後還需要配送車、配送站、快遞員,商品才能最終到達使用者手中。
一般情況下,快遞是不能直達的,需要先轉發到對應的配送站,然後由配送站再進行派件。
配送車就是實體媒體,配送站就是網關, 快遞員就是路由器,收貨位址就是IP位址,聯系方式就是MAC位址。
快遞員負責把包裹轉發到各個配送站,配送站根據收獲位址裡的省市區,确認是否需要繼續轉發到其他配送站,當包裹到達了目标配送站以後,配送站再根據聯系方式找到收件人進行派件。
有了整體概念以後,下面我們詳細了解一下各層的分工。
網絡通信就是把有特定意義的資料通過實體媒體傳送給對方,單純的發送 0 和 1 是沒有意義的,要傳輸有意義的資料,就需要以位元組為機關對 0 和 1 進行分組,并且要辨別好每一組電信号的資訊特征,然後按照分組的順序依次發送。以太網規定一組電信号就是一個資料包,一個資料包被稱為一幀, 制定這個規則的協定就是以太網協定。一個完整的以太網資料包如下圖所示:
整個資料幀由首部、資料和尾部三部分組成,首部固定為14個位元組,包含了目标MAC位址、源MAC位址和類型;資料最短為46個位元組,最長為1500個位元組,如果需要傳輸的資料很長,就必須分割成多個幀進行發送;尾部固定為4個位元組,表示資料幀校驗序列,用于确定資料包在傳輸過程中是否損壞。是以,以太網協定通過對電信号進行分組并形成資料幀,然後通過實體媒體把資料幀發送給接收方。那麼以太網如何來識接收方的身份呢?
以太網規協定定,接入網絡的裝置都必須安裝網絡擴充卡,即網卡, 資料包必須是從一塊網卡傳送到另一塊網卡。而網卡位址就是資料包的發送位址和接收位址,也就是幀首部所包含的MAC位址,MAC位址是每塊網卡的身份辨別,就如同我們身份證上的身份證号碼,具有全球唯一性。MAC位址采用十六進制辨別,共6個位元組, 前三個位元組是廠商編号,後三個位元組是網卡流水号,例如 4C-0F-6E-12-D2-19
有了MAC位址以後,以太網采用廣播形式,把資料包發給該子網内所有主機,子網内每台主機在接收到這個包以後,都會讀取首部裡的目标MAC位址,然後和自己的MAC位址進行對比,如果相同就做下一步處理,如果不同,就丢棄這個包。
是以鍊路層的主要工作就是對電信号進行分組并形成具有特定意義的資料幀,然後以廣播的形式通過實體媒體發送給接收方。
對于上面的過程,有幾個細節問題值得我們思考:
發送者如何知道接收者的MAC位址? 發送者如何知道接收者和自己同屬一個子網? 如果接收者和自己不在同一個子網,資料包如何發給對方?
為了解決這些問題,網絡層引入了三個協定,分别是IP協定、ARP協定、路由協定。
通過前面的介紹我們知道,MAC位址隻與廠商有關,與所處的網絡無關,是以無法通過MAC位址來判斷兩台主機是否屬于同一個子網。
是以,網絡層引入了IP協定,制定了一套新位址,使得我們能夠區分兩台主機是否同屬一個網絡,這套位址就是網絡位址,也就是所謂的IP位址。
IP位址目前有兩個版本,分别是IPv4和IPv6,IPv4是一個32位的位址,常采用4個十進制數字表示。IP協定将這個32位的位址分為兩部分,前面部分代表網絡位址,後面部分表示該主機在區域網路中的位址。由于各類位址的分法不盡相同,以C類位址192.168.24.1為例,其中前24位就是網絡位址,後8位就是主機位址。是以, 如果兩個IP位址在同一個子網内,則網絡位址一定相同。為了判斷IP位址中的網絡位址,IP協定還引入了子網路遮罩, IP位址和子網路遮罩通過按位與運算後就可以得到網絡位址。
由于發送者和接收者的IP位址是已知的(應用層的協定會傳入), 是以我們隻要通過子網路遮罩對兩個IP位址進行AND運算後就能夠判斷雙方是否在同一個子網了。
即位址解析協定,是根據IP位址擷取MAC位址的一個網絡層協定。其工作原理如下:
ARP首先會發起一個請求資料包,資料包的首部包含了目标主機的IP位址,然後這個資料包會在鍊路層進行再次包裝,生成以太網資料包,最終由以太網廣播給子網内的所有主機,每一台主機都會接收到這個資料包,并取出标頭裡的IP位址,然後和自己的IP位址進行比較,如果相同就傳回自己的MAC位址,如果不同就丢棄該資料包。ARP接收傳回消息,以此确定目标機的MAC位址;與此同時,ARP還會将傳回的MAC位址與對應的IP位址存入本機ARP緩存中并保留一定時間,下次請求時直接查詢ARP緩存以節約資源。cmd輸入 arp -a 就可以查詢本機緩存的ARP資料。
通過ARP協定的工作原理可以發現,ARP的MAC尋址還是局限在同一個子網中,是以網絡層引入了路由協定,首先通過IP協定來判斷兩台主機是否在同一個子網中,如果在同一個子網,就通過ARP協定查詢對應的MAC位址,然後以廣播的形式向該子網内的主機發送資料包;如果不在同一個子網,以太網會将該資料包轉發給本子網的網關進行路由。網關是網際網路上子網與子網之間的橋梁,是以網關會進行多次轉發,最終将該資料包轉發到目标IP所在的子網中,然後再通過ARP擷取目标機MAC,最終也是通過廣播形式将資料包發送給接收方。
而完成這個路由協定的實體裝置就是路由器,在錯綜複雜的網絡世界裡,路由器扮演者交通樞紐的角色,它會根據信道情況,選擇并設定路由,以最佳路徑來轉發資料包。
在網絡層被包裝的資料包就叫IP資料包,IPv4資料包的結構如下圖所示:
IP資料包由首部和資料兩部分組成,首部長度為20個位元組,主要包含了目标IP位址和源IP位址,目标IP位址是網關路由的線索和依據;資料部分的最大長度為65515位元組,理論上一個IP資料包的總長度可以達到65535個位元組,而以太網資料包的最大長度是1500個字元,如果超過這個大小,就需要對IP資料包進行分割,分成多幀發送。
是以,網絡層的主要工作是定義網絡位址,區分網段,子網内MAC尋址,對于不同子網的資料包進行路由。
鍊路層定義了主機的身份,即MAC位址, 而網絡層定義了IP位址,明确了主機所在的網段,有了這兩個位址,資料包就從可以從一個主機發送到另一台主機。但實際上資料包是從一個主機的某個應用程式發出,然後由對方主機的應用程式接收。而每台電腦都有可能同時運作着很多個應用程式,是以當資料包被發送到主機上以後,是無法确定哪個應用程式要接收這個包。
是以傳輸層引入了UDP協定來解決這個問題,為了給每個應用程式辨別身份,UDP協定定義了端口,同一個主機上的每個應用程式都需要指定唯一的端口号,并且規定網絡中傳輸的資料包必須加上端口資訊。 這樣,當資料包到達主機以後,就可以根據端口号找到對應的應用程式了。UDP定義的資料包就叫做UDP資料包,結構如下所示:
UDP資料包由首部和資料兩部分組成,首部長度為8個位元組,主要包括源端口和目标端口;資料最大為65527個位元組,整個資料包的長度最大可達到65535個位元組。
UDP協定比較簡單,實作容易,但它沒有确認機制, 資料包一旦發出,無法知道對方是否收到,是以可靠性較差,為了解決這個問題,提高網絡可靠性,TCP協定就誕生了,TCP即傳輸控制協定,是一種面向連接配接的、可靠的、基于位元組流的通信協定。簡單來說TCP就是有确認機制的UDP協定,每發出一個資料包都要求确認,如果有一個資料包丢失,就收不到确認,發送方就必須重發這個資料包。
為了保證傳輸的可靠性,TCP 協定在 UDP 基礎之上建立了三次對話的确認機制,也就是說,在正式收發資料前,必須和對方建立可靠的連接配接。由于建立過程較為複雜,我們在這裡做一個形象的描述:
主機A:我想發資料給你,可以麼? 主機B:可以,你什麼時候發? 主機A:我馬上發,你接着!
經過三次對話之後,主機A才會向主機B發送正式資料,而UDP是面向非連接配接的協定,它不與對方建立連接配接,而是直接就把資料包發過去了。是以 TCP 能夠保證資料包在傳輸過程中不被丢失,但美好的事物必然是要付出代價的,相比 UDP,TCP 實作過程複雜,消耗連接配接資源多,傳輸速度慢。
TCP 資料包和 UDP 一樣,都是由首部和資料兩部分組成,唯一不同的是,TCP 資料包沒有長度限制,理論上可以無限長,但是為了保證網絡的效率,通常 TCP 資料包的長度不會超過IP資料包的長度,以確定單個 TCP 資料包不必再分割。
總結一下,傳輸層的主要工作是定義端口,辨別應用程式身份,實作端口到端口的通信,TCP協定可以保證資料傳輸的可靠性。
理論上講,有了以上三層協定的支援,資料已經可以從一個主機上的應用程式傳輸到另一台主機的應用程式了,但此時傳過來的資料是位元組流,不能很好的被程式識别,操作性差。是以,應用層定義了各種各樣的協定來規範資料格式,常見的有 HTTP、FTP、SMTP 等,HTTP 是一種比較常用的應用層協定,主要用于B/S架構之間的資料通信,其封包格式如下:
在 Resquest Headers 中,Accept 表示用戶端期望接收的資料格式,而 ContentType 則表示用戶端發送的資料格式;在 Response Headers 中,ContentType 表示服務端響應的資料格式,這裡定義的格式,一般是和 Resquest Headers 中 Accept 定義的格式是一緻的。
有了這個規範以後,服務端收到請求以後,就能正确的解析用戶端發來的資料,當請求處理完以後,再按照用戶端要求的格式傳回,用戶端收到結果後,按照服務端傳回的格式進行解析。
是以應用層的主要工作就是定義資料格式并按照對應的格式解讀資料。
首先我們梳理一下每層模型的職責:
鍊路層:對0和1進行分組,定義資料幀,确認主機的實體位址,傳輸資料;
網絡層:定義IP位址,确認主機所在的網絡位置,并通過IP進行MAC尋址,對外網資料包進行路由轉發;
傳輸層:定義端口,确認主機上應用程式的身份,并将資料包交給對應的應用程式;
應用層:定義資料格式,并按照對應的格式解讀資料。
然後再把每層模型的職責串聯起來,用一句通俗易懂的話講就是:
當你輸入一個網址并按下Enter鍵的時候,首先,應用層協定對該請求包做了格式定義;緊接着傳輸層協定加上了雙方的端口号,确認了雙方通信的應用程式;然後網絡協定加上了雙方的IP位址,确認了雙方的網絡位置;最後鍊路層協定加上了雙方的MAC位址,确認了雙方的實體位置,同時将資料進行分組,形成資料幀,采用廣播方式,通過傳輸媒體發送給對方主機。而對于不同網段,該資料包首先會轉發給網關路由器,經過多次轉發後,最終被發送到目标主機。目标機接收到資料包後,采用對應的協定,對幀資料進行組裝,然後再通過一層一層的協定進行解析,最終被應用層的協定解析并交給伺服器處理。
以上内容是對TCP/IP四層模型做了簡單的介紹,而實際上每一層模型都有很多協定,每個協定要做的事情也很多,但我們首先得有一個清晰的脈絡結構,掌握每一層模型最基本的作用,然後再去豐富細枝末節的東西,也許會更容易了解。
原創釋出 @一像素 2017.06.29
更新: 2018.06.06
參考文獻:
[1] 網際網路協定入門(一)
[2] TCP/IP協定知識科普