漫談網絡通信——從OSI網絡模型到TCP/IP協議族


  OSI七層模型

  OSI(Open System Interconnection,開放系統互聯)七層網絡模型成為開放式系統互聯參考模型,是一個把網絡通信在邏輯上的定義,也可以理解成為定義了通用的網絡通信規范。而我們的數據在網絡中傳輸的過程,實際上就是如下圖的封裝和解封裝的過程,發送方通過各種封裝處理,把數據轉換成比特流的形式,比特流在信號傳輸的硬件媒介中傳輸,接收方再把比特流進行解封裝處理。

 

 

1.物理層

  規定了如何為網絡通信實現最底層的物理連接,以及物理設備的機械、電氣、功能和過程特性。如:如何使用電纜和接頭的類型、用來傳送信號的電壓等。需要注意的是,網絡通信過程中所需的物理媒介(網線、線纜等),其實並不屬於物理層,因為物理層實際上是一種規定,規定這些物理媒介設備在連接網絡時的各種規格、參數以及工作方式。但是同時,雙絞線、線纜等物理媒介又是物理層的實現。

 

2.數據鏈路層

  規定了如何進行物理地址尋址、如何在物理線路上進行數據(幀frame)的可靠傳遞以及流量控制。

  數據鏈路層協議有SLIP協議、CSLIP協議、PPP協議等。交換機,對幀解碼並根據幀中包含的信息把數據發送到正確的接收方,所以交換機是工作在數據鏈路層的。

 

3.網絡層

  規定了通過哪些網絡節點、什么樣的網絡路徑來將數據(數據包)從發送方發送到接收方。在網絡層中,確定了從節點A發數據到節點B的網絡路徑,經過哪些節點。網絡層既可以建立LAN通信系統,更主要的是可以在WAN網絡系統中建立通信,這是因為它有自己的路由地址結構,通過路由協議(又稱可路由協議)進行網絡通信的路由工作。

 

4.傳輸層

  負責總體的數據傳輸和數據控制,提供端到端的交換數據的機制。傳輸層對數據(段)進行分割和重組,並且進行流量控制和根據接收方的接收數據能力確定適當的傳輸速率。例如以太網無法處理大於1500字節的數據包,傳輸層將數據分割成數據片段,並對小數據片段進行序列編號。接收方的傳輸層將根據序列編號對數據進行重組。

  傳輸層協議有TCP協議、UDP協議等。

 

5.會話層

  在網絡中的兩個節點之間建立、維持和終止通信。

 

6.表示層

  在應用程序和網絡之間對數據進行格式化,使之能夠被另一方理解。即發送方的表示層將應用程序數據的抽象語法轉換成網絡適用於OSI網絡傳輸的傳送語法,接收方則相反。除此之外,表示層還可對數據進行加密與解密。

 

7.應用層

  最頂層的OSI層,為應用程序提供網絡服務。如為電子郵件、文件傳輸功能提供協議支持。

  應用層協議有HTTP協議、FTP協議、SMTP協議等。

 

  什么是TCP/IP協議?

  TCP/IP協議定義了今天的電子設備如何連入internet網絡,以及數據如何在他們之間傳輸的標准。在今天的基於TCP/IP的互聯網誕生之前,能夠使用接口通信處理實現互聯互通的電腦並不多,而且大部分電腦之間信息的交換並不兼容。后來好幾個牛逼哄哄的歪果仁開始搗鼓一些協議,能夠讓電腦之間進行通信。終於在1974年12月,Bob Kahn和Vinton G.Cerf帶領的團隊首先制定出了通過詳細定義的TCP/IP協議標准。當時作了一個試驗,將信息包通過點對點的衛星網絡,再通過陸地電纜,再通過衛星網絡,再由地面傳輸,貫串歐洲和美國,經過各種電腦系統,全程9.4萬公里竟然沒有丟失一個數據位,遠距離的可靠數據傳輸證明了TCP/IP協議的成功。1983年1月1日,運行較長時期曾被人們習慣了的NCP被停止使用,TCP/IP協議作為因特網上所有主機間的共同協議,從此以后被作為一種必須遵守的規則被肯定和應用。(讓我們為Bob Kahn和Vinton G.Cerf兩位老爺爺撒花鼓掌吧👏👏👏)

  從“TCP/IP”名字上來看,貌似這只是tcp協議和ip協議,但是實際上,這是很多協議(有人說有幾百個協議,感覺待考證)的集合。由於知識廣度和時間限制,將不對TCP/IP協議進行全面剖析,主要對其中比較重要的幾個點進行闡述。

  從概念上來講,TCP/IP協議族則把7層網絡模型合並成4層,其對應關系如下:

 

  

 

  各層協議舉例如下:

  

 

  TCP/IP——網絡接口層

  主要作用一:數據封裝/解封裝成幀(frame)。為了保證可靠傳輸,網絡層傳過來的數據在這里被加工成了可被物理層傳輸的結構包——幀。幀中除了包括需要傳輸的數據外,還包括發送方和接收方的物理地址以及檢錯和控制信息。其中的物理地址確定了幀將發送到何處,檢錯和控制信息則是用來保證數據的無差錯到達。數據幀結構如下(Address均為mac地址):

    

 

  主要作用二:控制幀傳輸。控制幀的傳輸主要體現在反饋重發、計時器、幀序號方面。接收方通過對幀的差錯編碼(奇偶校驗碼或 CRC 碼)的檢查,來判斷幀在傳輸過程中是否出錯,並向發送發進行反饋,如果傳輸發生差錯,則需要重發糾正。作為發送發,如果在發送幀后,會同時啟動定時器,如果幀發送后在一定時間內沒有收到反饋,為了避免傳輸停滯不前,則在計時器Timeou后認為幀傳輸出錯,自動重發。為了避免多次收到同一幀並將其遞交給網絡層的情況發生,則需要對每個發送的幀進行編號,接收方以此來判斷該幀是否重復接受了。

  主要作用三:流量控制。由於收發雙方各自使用的設備工作速率和緩沖存儲空間的差異,可能出現發送方的發送能力大於接收方接收能力的現象,此時若不對發送方的發送速率做適當的限制,前面來不及接收的幀將被后面不斷發送來的幀“淹沒”,從而造成幀的丟失而出錯。由此可見,流量控制實際上是對發送方數據流量的控制,使其發送速率不超過接收方的速率。所以需要一些規則使得發送方知道在什么情況下可以接着發送下一幀,而在什么情況下必須暫停發送,以等待收到某種反饋信息后再繼續發送。

 

  TCP/IP——網絡層

  說到網絡層不得不提的就是IP協議,它是TCP/IP協議族中最為核心的協議。所有的TCP、UDP、ICMP、IGMP協議數據都以IP數據報格式傳輸。IP協議提供的是不可靠的、無連接的數據報傳輸服務。不可靠是指IP協議不會保證數據報能否成功到達目的地,僅提供傳輸服務,傳輸出錯,則會丟棄出錯的數據報。無連接是指IP協議對數據報的處理是獨立的,這也意味着接收方不一定會按照發送順序接收數據報。

IP數據報格式如下:

    

 

IP地址分類:

  

 

  

 

 

子網划分:

  一個有500台主機的網絡,如果使用C類地址,則無法滿足主機數量需求,使用B類地址則會造成IP地址的浪費。由此,需要在ABC類網絡的基礎上進行子網划分:即占用主機號的前幾位表示子網號。子網掩碼的概念由此被引入。

  

  子網掩碼中的 1 標識了 IP 地址中相應的網絡號,0 標識了主機號。將 IP 地址和子網掩碼進行邏輯與運算 ,結果就能得到網絡號和子網號。

 

IP路由:

  如果發送方和接收方在直接點對點連接或者在一個共享網絡上,那么IP數據報則可以直接送達。但多數情況下,兩台主機互聯,需要通過多台路由器,需要路由轉發送達消息。這個路由的過程是怎樣的呢?這里有個重要的角色——路由表。路由表是一張存儲在內存中的記錄路由信息的表,定義着到達特定網絡終端的路徑,在某些情況下,還有一些與這些路徑相關的度量。路由表中保存的信息,則用來指導消息從發送方到達接受方的網絡路由路徑。Linux下查看路由表的命令是route -n,mac os查看路由表的命令是netstat -nr。

  

 

  有了路由表,網絡路徑的確認過程則如下所示:

  

 

  接收到數據報的路由器按照它自己的理由表進行繼續轉發,直到到達目的地址。而除了在路由尋址過程中失敗會導致丟棄數據報之外,IP數據報的TTL(生命周期)被減為0,則該IP數據報也會被丟棄。

 

  網絡層還有幾個比較重要的協議,ARP(Address Resolution Protocol地址解析協議)、ICMP(Internet Control Message Protocol報文控制協議)、IGMP(Internet Group Management Protocol組管理協議),這里不做具體說明啦。

 

  TCP/IP——傳輸層

  無論參考OSI還是TCP/IP的網絡模型,我們從傳輸層向更底層看,各層的協議都是在直接或間接的服務於主機與主機之間的通信,而傳輸層則是在進程與進程通信層面上的。傳輸層有兩個重要的協議——TCP協議和UDP協議。不同的應用進程則使用不同的傳輸層協議。

   

 

  端口的作用則正是體現在傳輸層的。用來區分網絡消息由主機上的那一個進程處理。端口號有 0~65535 的編號,其中0~1023為系統端口號。

  

 

UDP協議:

  UDP(User Datagram Protocol)即用戶數據報協議,其傳輸機制決定了它的最大優點——快,同時也決定了它最大的缺點——不可靠、不穩定。

  UDP是無連接的,發送數據之前不需要建立連接(TCP需要)。減少了開銷和延時。

  UDP是面向報文的,對IP數據報只做簡單封裝(8字節UDP報頭)。減少報頭開銷。

  UDP沒有阻塞機制,寧願阻塞時丟棄數據不傳,也不阻塞造成延時。

  UDP支持一對一、一對多、多對一、多對多通信。

    

  UDP報文結構:

    

 

 

 

TCP協議:

  TCP(Transmission Control Protocol)傳輸控制協議,相對於UDP,TCP是面向連接的、提供可靠的數據傳輸服務。同時也是較UDP開銷較大的、傳輸速度較慢的。

  TCP提供可靠的、面向連接的數據傳輸服務。使用TCP通信之前,需要進行“三次握手”建立連接,通信結束后還要使用“四次揮手”斷開連接。

  TCP是點對點的連接。一條TCP連接只能連接兩個端點。

  TCP 提供可靠傳輸,無差錯、不丟失、不重復、按順序。

  TCP 提供全雙工通信,允許通信雙方任何時候都能發送數據,發送方設有發送緩存,接收方設有接收緩存。

  TCP 面向字節流 。TCP 並不知道所傳輸的數據的含義,僅把數據看作一連串的字節序列,它也不保證接收方收到的數據塊和發送方發出的數據塊具有大小對應關系。

 

  TCP報文結構:

  

  TCP是面向字節流的,通過 TCP 傳送的字節流中的每個字節都按順序編號,而報頭中的Sequence Number字段值則指的是本報文段數據的第一個字節的序號。Acknowledgment Number是期望收到對方下個報文段的第一個數據字節的序號。

  Offset:占4位,指 TCP 報文段的報頭長度,包括固定的20字節和TCP Options字段。

  Reserved:占6位,保留為今后使用,目前為0。

  TCP flags的C、E、U、A、P、R、S、F字段用來說明該報文的性質。意義如下: 

    C(CWR)和E(ECE)用來支持ECN(顯示阻塞通告)。

    U(URGENT):當 URG=1時,它告訴系統此報文中有緊急數據,應優先傳送(比如緊急關閉),這要與緊急指針字段配合使用。

    A(ACK):僅當 ACK=1時確認號字段才有效。建立 TCP 連接后,所有報文段都必須把 ACK 字段置為 1。

    P(PUSH):若TCP連接的一端希望另一端立即響應,PSH字段便可以“催促”對方,不再等到緩存區填滿才發送。

    R(RESET):若 TCP 連接出現嚴重差錯,RST 置為 1,斷開 TCP 連接,再重新建立連接。

    S(SYN):用於建立和釋放連接,當SYN=1時,表示建立連接。

    F(FIN):用於釋放連接,當 FIN=1,表明發送方已經發送完畢,要求釋放TCP 連接。

  Window:占2個字節。窗口值是指發送者自己的接收窗口大小,因為接收緩存的空間有限。 

  CheckSum:占2個字節。和UDP報文一樣,有一個檢驗和,用於檢查報文是否在傳輸過程中出差錯。

  Urgent Pointer:占2字節。當URG=1時才有效,指出本報文段緊急數據的字節數。

 

  TCP建立連接的三次握手:

  

 

  (1)Client首先向Server發送連接請求報文段,同步自己的seq(x),Client進入SYN_SENT狀態。

  (2)Server收到Client的連接請求報文段,返回給Client自己的seq(y)以及ack(x+1),Server進入SYN_REVD狀態。

  (3)Client收到Server的返回確認,再次向服務器發送確認報文段ack(y+1),這個報文段已經可以攜帶數據了。Client進入ESTABLISHED狀態。

  (4)Server再次收到Client的確認信息后,進入ESTABLISHED狀態。

  TCP連接至此建立起來了。為什么要做三次握手呢?握手的過程實際上是在通知對方自己的初始化序號(Initial Sequence Number),簡稱ISN,也就是上圖中的x和y。x和y會被當作之后傳輸數據的一個依據,以保證TCP報文在傳輸過程中不會混亂。

  我們回到TCP Header結構來看,Sequence Number和Acknowledgment Number都是占32位,所以seq和ack的取值范圍是0 ~ 2^32-1。seq和ack每增加到2^32-1,則重新從0開始。值得一提的是,seq的初始值(ISN)並不是每次都從0開始的。我們設想一下,如果是從0開始,那么當TCP三次握手建立連接完成后,Client發送了30個報文,然后Client斷線了。於是Client重連,再次用0作為初始的seq,這樣就會出現兩個報文具有相同的seq,就出現了混亂。事實上TCP的做法是每隔4微秒就對ISN做一次加1操作,當ISN到達2^32-1后再次從0開始的時候,已經過去了幾個小時,之前的seq=0的報文已經不存在於這次連接中了,這樣就避免了上面的問題。

  

  TCP斷開連接的四次揮手:

  

  (1)Client向Server發送斷開連接請求的報文段,seq=m(m為Client最后一次向Server發送報文段的最后一個字節序號加1),Client進入FIN-WAIT-1狀態。

  (2)Server收到斷開報文段后,向Client發送確認報文段,seq=n(n為Server最后一次向Client發送報文段的最后一個字節序號加1),ack=m+1,Server進入CLOSE-WAIT狀態。此時這個TCP連接處於半開半閉狀態,Server發送數據的話,Client仍然可以接收到。

  (3)Server向Client發送斷開確認報文段,seq=u(u為半開半閉狀態下Server最后一次向Client發送報文段的最后一個字節序號加1),ack=m+1,Server進入LAST-ACK狀態。

  (4)Client收到Server的斷開確認報文段后,向Server發送確認斷開報文,seq=m+1,ack=u+1,Client進入TIME-WAIT狀態。

  (5)Server收到Client的確認斷開報文,進入CLOSED狀態,斷開了TCP連接。

  (6)Client在TIME-WAIT狀態等待一段時間(時間為2*MSL((Maximum Segment Life)),確認Client向Server發送的最后一次斷開確認到達(如果沒有到達,Server會重發步驟(3)中的斷開確認報文段給Client,告訴Client你的最后一次確認斷開沒有收到)。如果Client在TIME-WAIT過程中沒有再次收到Server的報文段,就進入CLOSES狀態。TCP連接至此斷開。

  

  TCP連接可靠性的體現:

  (1)TCP報文段的長度可變,根據收發雙方的緩存狀態、網絡狀態而調整。

  (2)當TCP收到發自TCP連接另一端的數據,它將發送一個確認。

  (3)當TCP發出一個段后,它啟動一個定時器,等待目的端確認收到這個報文段,如果不能及時收到一個確認,將重發這個報文段。

  (4)TCP將保持它首部和數據的檢驗和。如果通過檢驗和發現報文段有差錯,這個報文段將被丟棄,等待超時重傳。

  (5)TCP將數據按字節排序,報文段中有序號,以確保順序的正確性。

  (6)TCP還能提供流量控制。TCP連接的每一方都有收發緩存。TCP的接收端只允許另一端發送接收端緩沖區所能接納的數據。這將防止較快主機致使較慢主機的緩沖區溢出。

  需要注意的是,TCP報文傳輸采用接受后返回確認的方式來保證報文傳輸的可靠性,並不是意味着發送方在發送一個報文段后就進入等待確認狀態,讓后面的報文段等着。也不是接收方在接收到一個報文后,對每一個報文都進行回復確認。

  真實的情況是,對於發送方,在發送一個報文段后,復制一份該報文段的副本,然后繼續進行下一個報文段的發送,如果沒有得到發送方的回復確認,就對該報文段進行超時重發。對於接收方來說,則采用“積累確認”的方式進行回復。接收者收到多個連續的報文段后,只回復確認最后一個報文段,表示在這之前的數據都已收到。以此達到提升傳輸效率的目的。

 

  TCP的流量控制和阻塞控制:

  由於接收方緩存的限制,發送窗口不能大於接收方接收窗口。在報文段首部有一個字段就叫做窗口(rwnd),這便是用於告訴對方自己的接收窗口,可見窗口的大小是可以變化的。 

  

  總結起來如上圖,TCP的流量和阻塞控制采用“慢啟動”、“加性增”、“乘性減”的策略。

  慢啟動:初始的窗口值很小,但是按指數規律漸漸增長,直到達到慢開始門限(ssthresh)。

  加性增:窗口值達到慢開始門限后,每發送一個報文段,窗口值增加一個單位量。

  乘性減:無論什么階段,只要出現超時,則把窗口值減小一半。

 

  TCP/IP——應用層

   關於應用層協議,不同的應用或者具體來說同一種應用不同的需求,都會使用不同的應用層協議,作為互聯網軟件開發工程師,我們可能對應用層協議最為熟悉,這篇文章中將不再對應用層協議進行總結。

  

 

  


  寫在最后:

    實不相瞞,在寫下這篇文章之前,文章中至少有一半的內容(😏甚至不止一半)是作者不完全掌握或者知其然不知其所以然的,本來想把文章題目叫做《深度分析....》,但是覺得技術文章動不動的“深度分析”可能只是相較於自己的知識層面的深度,而非真正客觀意義上的深度技術分析,所以本着謙虛和嚴謹的態度把題目改成了《漫談...》,想通過這種方式,對網絡通信這一塊做一個總結性的學習。講真,這篇文章的部分內容 = 網絡技術文章借鑒 + 個人理解,本人非專家,如有錯誤,歡迎斧正!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM