【計算機網絡】傳輸層知識點總結

TCP/IP 是互聯網相關的各類協議族的總稱,其中包括 TCPUDP,IP,FTP,HTTP,ICMP,SMTP 等。TCP/IP 中兩個具有代表性的傳輸層協議是 TCP 和 UDP:
在這裏插入圖片描述
傳輸層:

  • 作用:爲上面的應用層提供通信服務,提供應用進程間的邏輯通信
  • 在OSI七層參考模型中,傳輸層是面向通信部分的最高層用戶功能中的最底層
  • 兩大重要的功能:1)複用,2)分用。複用是指,在發送端,多個應用進程共用一個傳輸層。分用是指,在接收端,傳輸層會根據端口號將數據分派給不同的應用進程
  • 傳輸層和網絡層的區別:1)網絡層爲不同主機提供通信服務,而傳輸層爲不同主機的不同應用提供通信服務;2)網絡層只對報文頭部進行差錯檢測,而傳輸層對整個報文進行差錯檢測

傳輸層的兩個主要協議:

  • 傳輸控制協議 TCP(Transmission Control Protocol)
  • 用戶數據報協議 UDP(User Datagram Protocol)

用戶數據報協議 UDP

概念: UDP(User Datagram Protocol)在 OSI 模型中處於傳輸層,屬於無連接協議。UDP 盡最大可能交付,沒有擁塞控制,面向報文,支持一對一、一對多、多對一和多對多的交互通信。

用戶數據報協議 UDP 的特點:

  • 面向無連接(減少開銷和發送時延):通信前不需要建立連接,通信結束也無需釋放連接
  • 盡最大努力交付:它是盡力而爲交付,不能確保每一個數據報都送達
  • 面向報文(對於應用程序傳下來的報文不合並也不拆分,只是添加 UDP 首部)
  • 沒有擁塞控制(當網絡出現堵塞不會使源主機的發送速率降低,這對實時視頻會議比較重要,即允許在網絡發生堵塞時丟失一些數據,但不允許數據有太大時延)
  • 支持一對一,一對多,多對一,多對多的交互通信(單播、多播、廣播),而TCP只支持一對一通信
  • 首部開銷小(只有 8 個字節),而TCP頭部至少20字節
  • 不可靠性

(1)面向無連接:不需要像 TCP 一樣在發送數據前進行三次握手,想發就直接發了,它只是數據的搬運工,不會對數據進行任何拆分和拼接操作。具體來說,就是在發送端,應用層將數據傳遞給傳輸層的 UDP 協議,UDP 只會給數據增加一個 UDP 頭標識下是 UDP 協議,然後就傳遞給網絡層了;在接收端,網絡層將數據傳遞給傳輸層,UDP 只去除 IP 報文頭就傳遞給應用層,不會任何拼接操作。
(2)有單播、多播、廣播功能:支持一對一、一對多、多對多、多對一的方式傳輸方式。
(3)面向報文:所謂面向報文就是指UDP數據傳輸的單位是報文,且不會對數據作任何拆分和拼接操作。在發送端,應用程序給傳輸層的UDP什麼樣的數據,UDP不會對數據進行切分,只增加一個UDP頭並交給網絡層(IP層)。在接收端,UDP收到網絡層的數據報後,去除IP數據報頭部後遍交給應用層,不會作任何拼接操作。
(4)不可靠性:首先不可靠性體現在無連接上,通信都不需要建立連接,想發就發,這樣的情況肯定不可靠。並且收到什麼數據就傳遞什麼數據,並且也不會備份數據,發送數據也不會關心對方是否已經正確接收到數據了。再者網絡環境時好時壞,但是 UDP 因爲沒有擁塞控制,一直會以恆定的速度發送數據。即使網絡條件不好,也不會對發送速率進行調整。這樣實現的弊端就是在網絡條件不好的情況下可能會導致丟包,但是優點也很明顯,在某些實時性要求高的場景(比如電話會議)就需要使用 UDP 而不是 TCP。UDP只會把想發的數據報文一股腦的丟給對方,並不在意數據有無安全完整到達。
(5)頭部開銷小:只有 8 字節,相比 TCP 的至少 20 個字節要少得多,在傳輸數據報文時是很高效的。UDP 頭部包括:端口號 + 報文長度 + 數據報文的檢驗。
(6)沒有擁塞控制:UDP始終以恆定的速率發送數據,並不會根據網絡擁塞情況對發送速率作調整。這種方式有利有弊。弊端:網絡擁塞時有些報文可能會丟失,因此UDP不可靠。優點:有些使用場景允許報文丟失,如:直播、語音通話,但對實時性要求很高,此時UDP還是很有用武之地的。

UDP報文頭: 包括源端口,目的端口,整個數據報的長度,整個數據報的檢驗和。
在這裏插入圖片描述

傳輸控制協議 TCP

概念: TCP(Transmission Control Protocol)是 面向連接的提供可靠交付,有流量控制擁塞控制,提供全雙工通信,面向字節流,每一條 TCP 連接只能是點對點的(一對一)的傳輸層通信協議。TCP將用戶數據打包成報文段,它發送後會啓動一個定時器。

傳輸控制協議 TCP 的特點:

  • 面向連接的:通信前需要建立連接,通信結束需要釋放連接
  • 僅支持單播
  • 提供可靠交付:可靠指的是TCP發送的數據無重複、無丟失、無錯誤、與發送端順序一致
  • 面向字節流:把應用層傳下來的報文看成字節流,把字節流組織成大小不等的數據塊
  • 提供擁塞控制
  • 每一條 TCP 連接只能是點對點的:TCP只能提供點到點的通信,而UDP可以任意方式的通信
  • 提供全雙工通信:全雙工通信指的是TCP的兩端既可以作爲發送端,也可以作爲接收端

(1)面向連接:面向連接,是指發送數據之前必須在兩端建立連接。建立連接的方法是“三次握手”,這樣能建立可靠的連接。建立連接,是爲數據的可靠傳輸打下了基礎。
(2)僅支持單播:每條TCP傳輸連接只能有兩個端點,只能進行點對點的數據傳輸,不支持多播和廣播傳輸方式。
(3)面向字節流:TCP 不像 UDP 一樣那樣一個個報文獨立地傳輸,而是在不保留報文邊界的情況下以字節流方式進行傳輸。所謂面向字節流指的是TCP以字節爲單位。雖然傳輸的過程中數據被劃分成一個個數據報,但這只是爲了方便傳輸,接收端最終接受到的數據將與發送端的數據一模一樣。
(4)可靠傳輸:對於可靠傳輸,判斷丟包,誤碼靠的是TCP的段編號以及確認號。TCP爲了保證報文傳輸的可靠,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然後接收端實體對已成功收到的字節發回一個相應的確認(ACK);如果發送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的數據(假設丟失了)將會被重傳。
(5)提供擁塞控制:當網絡出現擁塞的時候,TCP能夠減小向網絡注入數據的速率和數量,緩解擁塞。
(6)提供全雙工通信:TCP允許通信雙方的應用程序在任何時候都能發送數據,因爲TCP連接的兩端都設有緩存,用來臨時存放雙向通信的數據。當然,TCP可以立即發送一個數據段,也可以緩存一段時間以便一次發送更多的數據段(最大的數據段大小取決於MSS)。

TCP頭部: TCP頭部長度有20字節的固定部分,選項部分長度不定,但最多40字節,因此TCP頭部在20-60字節之間。
在這裏插入圖片描述
在這裏插入圖片描述

  • 源端口(Source Port):數據發起者的端口號
  • 目的端口(Destination Port):數據接收者的端口號(傳輸層和網絡層一大重要區別就是傳輸層指定了數據報發往的應用進程,因此需要端口號標識)
  • 序列號(Sequence Number,seq):用於在數據通信中解決網絡包亂序(reordering)問題,以保證應用層接收到的數據不會因爲網絡上的傳輸問題而亂序
  • 確認號(Acknowledgment Number,ack):表示當前主機作爲接收端時,期望接收的下一個字節的編號是多少,因此確認號是當前主機已經正確接收的最後一個字節序號(seq)+ 1
  • 報頭長度(Offset):存儲數據報頭部的長度,存儲報文頭中有多少個32bit,存儲長度爲 4bit,最大可表示(2 ^ 3+2 ^ 2+2 ^ 1 + 1)x 32bit = 60bytes 的報文頭
  • 保留字段(Reserved):均爲 0
  • 標識符(TCP Flags):TCP有 7 種標識符,用於表示TCP報文的性質。它們只能爲 0 或 1
  • 窗口大小(Window):用於實現TCP的流量控制
  • 檢驗和(Checksum):該字段檢驗的範圍包括頭部和數據這兩部分。由發端計算和存儲,並由收端進行驗證
  • 緊急指針(Urgent Pointer):緊急指針在 URG=1 時纔有效,它指出本報文段中的緊急數據的字節數
  • 選項字段(TCP Options):可選的,且長度可變,最長40字節,最常用的選項字段爲 MMS:最大報文長度

TCP連接與套接字:

  • TCP連接是一種抽象的概念,表示一條可以通信的鏈路。每條TCP連接有且僅有兩個端點,表示通信的雙方。且雙發在任意時刻都可以作爲發送者和接收者。
  • 一條TCP連接的兩端就是兩個套接字,套接字 = IP地址:端口號,因此,TCP連接 =(套接字1,套接字2)=(IP1:端口號1,IP2:端口號2)

TCP標識符(TCP Flags): TCP有 7 種標識符,用於表示TCP報文的性質。它們只能爲 0 或 1

  • URG = 1:當URG字段被置1,表示本數據報的數據部分包含緊急信息,此時緊急指針有效。
  • ACK = 1:ACK被置 1 後確認號字段纔有效,TCP規定,在連接建立後傳送的所有報文段都必須把ACK置1。
  • PSH = 1:當接收方收到PSH=1的報文後,會立即將數據交付給應用程序,而不會等到緩衝區滿後再提交。一些交互式應用需要這樣的功能,降低命令的響應時間。
  • RST = 1:當該值爲1時,表示當前TCP連接出現嚴重問題,必須要釋放重連。
  • SYN = 1:SYN在建立連接時使用。當SYN=1,ACK=0時,表示當前報文段是一個連接請求報文。當SYN=1,ACK=1時,表示當前報文段是一個同意建立連接的應答報文。
  • FIN = 1:FIN=1表示此報文段是一個釋放連接的請求報文。

1. TCP 三次握手

基本思想:讓我知道你已經知道了

TCP 協議中,主動發起請求的一端稱爲客戶端,被動連接的一端稱爲服務端。不管是客戶端還是服務端,TCP 連接建立完後都能發送和接收數據。
在這裏插入圖片描述
最初服務器和客戶端都爲 CLOSED 狀態。在通信開始前,雙方創建各自的傳輸控制塊(TCB)。
服務器創建完 TCB 後遍進入 LISTEN 狀態,此時準備接收客戶端發來的連接請求。

  • 第一次握手:服務器 B 處於 監聽(LISTEN) 狀態,此時客戶端 A 向 B 發送請求連接報文段。該報文段中 SYN = 1,ACK = 0,seq = x,A 進入 同步已發送(SYN-SENT) 狀態,等待服務器確認;(A 問 B 你可以嗎?)【SYN = 1,ACK = 0表示該報文段爲請求連接報文】【seq = x,x 爲本次 TCP 通信的字節流的初始序號,TCP 規定 SYN=1 的報文段不能有數據部分,但要消耗掉一個序號】
  • 第二次握手:服務器 B 收到 A 的連接請求報文段,如果同意建立連接,則向 A 發送連接確認:SYN = 1,ACK = 1,seq = y,ack = x + 1,進入 同步已收到(SYN-RCVD) 狀態;(B 告訴 A 我可以)【SYN = 1,ACK = 1表示該報文段爲連接同意的應答報文】【seq = y 表示服務端作爲發送者時,發送字節流的初始序號】【ack = x+1表示服務端希望下一個數據報發送序號從 x+1 開始的字節】
  • 第三次握手:客戶端 A 收到 B 同意連接的應答後,再向 B 發送一次確認報文段,該報文段頭部爲:ACK = 1,seq = x+1,ack = y+1,客戶端發送完這個確認報文後就進入 已建立連接(ESTABLISHED) 狀態(A 再告訴 B 我也可以)
  • B 收到 A 的確認後,B 也進入 已建立連接(ESTABLISHED) 狀態,完成三次握手

TCP 的三次握手還是挺有意思的,基本思想就是 “讓我知道你已經知道” 了。 服務器監聽請求,客戶端發起連接請求(第一次連接),請求在路上可能存在丟失的風險, 所以當請求到了服務器後如果服務器同意建立連接會給客戶端一個回信(第二次連接),告訴它:我已經收到請求,可以連接。 但是回信也存在一個問題,那就是回信能不能到客戶端?它需要客戶端給他一個回信說我已經收到批准通知了, 如果客戶端一直不回覆的話意味着客戶端沒有收到批准通知。 因此客戶端一收到批准通知就立馬回覆(第三次握手):OK 老鐵我收到你的批准通知了。至此,三次握手結束。

這種“讓我知道你已經知道了”的想法是一種約定俗成的 可靠信息交互的基本方式, 基於此想法構建的信息交互框架叫做協議。

相關解釋:

  • 序列號 seq:佔 4 個字節,用來標記數據段的順序,TCP 把連接中發送的所有數據字節都編上一個序號,第一個字節的編號由本地隨機產生;給字節編上序號後,就給每一個報文段指派一個序號;序列號 seq 就是這個報文段中的第一個字節的數據編號。
  • 確認號 ack:佔 4 個字節,期待收到對方下一個報文段的第一個數據字節的序號;序列號表示報文段攜帶數據的第一個字節的編號;而確認號指的是期望接收到下一個字節的編號;因此當前報文段最後一個字節的編號+1即爲確認號。
  • 確認號 ACK(標誌位):佔 1 位,當 ACK=1 時,表示確認號有效,反之無效。
  • 同步號 SYN(標誌位):連接建立時用於同步序號。當 SYN=1,ACK=0 時表示這是一個連接請求報文段。若同意連接,則在響應報文段中使得 SYN=1,ACK=1。因此,SYN=1 表示這是一個連接請求,或連接接受報文。SYN 這個標誌位只有在 TCP 建立連接時纔會被置 1,握手完成後 SYN 標誌位被置 0。
  • 終止號 FIN(標誌位):用來釋放一個連接。FIN=1 表示此報文段的發送方的數據已經發送完畢,並要求釋放運輸連接。
  • URG:緊急指針是否有效。爲1,表示某一位需要被優先處理。
  • PSH:提示接收端應用程序立即從TCP緩衝區把數據讀走。
  • RST:對方要求重新建立連接,復位。

ACK、SYN 和 FIN這些大寫的單詞表示標誌位,其值要麼是 1,要麼是 0;ack、seq小寫的單詞表示序號。

2. TCP 四次揮手

TCP連接是雙向的,因此在四次揮手中,前兩次揮手用於斷開一個方向的連接,後兩次揮手用於斷開另一方向的連接。
在這裏插入圖片描述

  • 第一次揮手:客戶端 A 發送連接釋放請求,並停止發送數據,該請求只有報文頭,主要參數:FIN = 1,seq = u。此時客戶端進入 **終止等待1(FIN-WAIT-1)**狀態;【FIN=1表示該報文段是一個連接釋放請求】【seq = u,u-1 是 A 向 B 發送的最後一個字節的序號】
  • 第二次揮手:服務器 B 收到 A 的釋放請求後發出確認,確認報文包括:ACK = 1,seq = v,ack = u + 1。此時 TCP 處於半關閉狀態,服務器進入 **關閉等待(CLOSE-WAIT)**狀態,B 能向 A 發數據但 A 不會向 B 發數據。此時 A 進入 **終止等待2(FIN-WAIT-2)**狀態,等待 B 傳輸最後的數據併發送連接釋放請求。第二次揮手完成後,A到B方向的連接已經釋放,B不會再接收數據,A也不會再發送數據。但B到A方向的連接仍然存在,B可以繼續向A發送數據。【ACK=1:除TCP連接請求報文段以外,TCP通信過程中所有數據報的ACK都爲1,表示應答】【seq=v,v-1是B向A發送的最後一個字節的序號】【ack = u+1 表示希望收到從第 u+1 個字節開始的報文段,並且已經成功接收了前 u 個字節】
  • 第三次揮手:當 B 不再需要連接時,向 A 發送連接釋放請求,請求頭:FIN = 1,ACK = 1,seq = w,ack = u + 1,此時 B 進入 **最後確認(LAST-ACK)**狀態,等待 A 的確認
  • 第四次揮手:A 收到 B 的請求釋放後進行確認,ACK = 1,ack = w + 1,B 進入 CLOSED 狀態,A 進入 TIME-WAIT 狀態,等待 2 MSL(最大報文存活時間)若沒有收到 B 的重發請求的話,就釋放連接並進入 CLOSED 狀態。

服務器結束 TCP 連接的時間要比客戶端早一些。

3. TCP可靠傳輸的實現

TCP的可靠性表現在:它嚮應用層提供的數據是無差錯的、有序的、無丟失的,簡單的說就是:TCP最終遞交給應用層的數據和發送者發送的數據是一模一樣的。

TCP採用了流量控制擁塞控制連續ARQ等技術來保證它的可靠性。

  1. 超時重傳:數據到達接收方,接收方需要發出一個確認應答,表示已經收到該數據段,並且確認序號會說明了它下一次需要接收的數據序列號。如果發送發遲遲未收到確認應答,那麼可能是發送的數據丟失,也可能是確認應答丟失,這時發送方在等待一定時間後會進行重傳。這個時間一般是2*RTT(報文段往返時間)+一個偏差值。
  2. 窗口控制:TCP會利用窗口控制來提高傳輸速度,意思是在一個窗口大小內,不用一定要等到應答才能發送下一段數據,窗口大小就是無需等待確認而可以繼續發送數據的最大值。如果不使用窗口控制,每一個沒收到確認應答的數據都要重發。使用窗口控制,如果數據段1001-2000丟失,後面數據每次傳輸,確認應答都會不停地發送序號爲1001的應答,表示我要接收1001開始的數據,發送端如果收到3次相同應答,就會立刻進行重發;但還有種情況有可能是數據都收到了,但是有的應答丟失了,這種情況不會進行重發,因爲發送端知道,如果是數據段丟失,接收端不會放過它的,會瘋狂向它提醒…
  3. 擁塞控制:慢啓動、擁塞避免、快速重傳

停止等待協議(ARQ協議)

ARQ(Automatic Repeat Request)自動重傳請求。顧名思義,當請求失敗時它會自動重傳,直到請求被正確接收爲止。這種機制保證了每個分組都能被正確接收。停止等待協議是一種 ARQ 協議。

停止等待協議的原理:

  • 無差錯的情況:A向B每發送一個分組,都要停止發送,等待B的確認應答;A只有收到了B的確認應答後才能發送下一個分組
  • 分組丟失 和 出現差錯 的情況:發送者擁有超時計時器。每發送一個分組便會啓動超時計時器,等待B的應答。若超時仍未收到應答,則A會重發剛纔的分組。分組出現差錯:若B收到分組,但通過檢查和字段發現分組在運輸途中出現差錯,它會直接丟棄該分組,並且不會有任何其他動作。A超時後便會重新發送該分組,直到B正確接收爲止。分組丟失:若分組在途中丟失,B並沒有收到分組,因此也不會有任何響應。當A超時後也會重傳分組,直到正確接收該分組的應答爲止。綜上所述:當分組丟失 或 出現差錯 的情況下,A都會超時重傳分組。
  • 應答丟失 和 應答遲到 的情況:TCP會給每個字節都打上序號,用於判斷該分組是否已經接收。應答丟失:若B正確收到分組,並已經返回應答,但應答在返回途中丟失了。此時A也收不到應答,從而超時重傳。緊接着B又收到了該分組。接收者根據序號來判斷當前收到的分組是否已經接收,若已接收則直接丟棄,並補上一個確認應答。應答遲到:若由於網絡擁塞,A遲遲收不到B發送的應答,因此會超時重傳。B收到該分組後,發現已經接收,便丟棄該分組,並向A補上確認應答。A收到應答後便繼續發送下一個分組。但經過了很長時間後,那個失效的應答最終抵達了A,此時A可根據序號判斷該分組已經接收,此時只需簡單丟棄即可。

停止等待協議的注意點:

  • 每發送完一個分組,該分組必須被保留,直到收到確認應答爲止
  • 必須給每個分組進行編號。以便按序接收,並判斷該分組是否已被接收
  • 必須設置超時計時器。每發送一個分組就要啓動計時器,超時就要重發分組
  • 計時器的超時時間要大於應答的平均返回時間,否則會出現很多不必要的重傳,降低傳輸效率。但超時時間也不能太長

滑動窗口協議(連續ARQ協議)

連續ARQ協議:在ARQ協議發送者每次只能發送一個分組,在應答到來前必須等待。而連續ARQ協議的發送者擁有一個發送窗口,發送者可以在沒有得到應答的情況下連續發送窗口中的分組。這樣降低了等待時間,提高了傳輸效率。(TCP保證其可靠性採用的是滑動窗口協議,停止等待協議是它的簡化版)

累計確認:在連續ARQ協議中,接收者也有個接收窗口,接收者並不需要每收到一個分組就返回一個應答,可以連續收到分組之後統一返回一個應答。這樣能節省流量。TCP頭部的ack字段就是用來累計確認,它表示已經確認的字節序號+1,也表示期望發送者發送的下一個分組的起始字節號。

發送窗口:發送窗口的大小由接收窗口的剩餘大小決定。接收者會把當前接收窗口的剩餘大小寫入應答 TCP 報文段的頭部,發送者收到應答後根據該值和當前網絡擁塞情況設置發送窗口的大小。發送窗口的大小是不斷變化的。
在這裏插入圖片描述
發送窗口由三個指針構成:p1,p2,p3

  • p1 指向發送窗口(黑色部分)的後沿(左側),它左邊的字節表示已經發送且已收到應答
  • p2 指向尚未發送的第一個字節
  • p3 指向發送窗口的前沿(右側),它右邊的字節尚未發送,且不允許發送

p1-p2 間的字節表示已經發送,但還沒收到確認應答。這部分的字節仍需保留,因爲可能還要超時重發。p2-p3 間的字節表示可以發送,但還沒有發送的字節。發送者每收到一個應答,後沿就可以向前移動指定的字節。此時若窗口大小仍然沒變,前沿也可以向前移動指定字節。

接收窗口:接收者收到的字節會存入接收窗口,接收者會對已經正確接收的有序字節進行累計確認,發送完確認應答後,接收窗口就可以向前移動指定字節。如果某些字節並未按序收到,接收者只會確認最後一個有序的字節,從而亂序的字節就會被重新發送。
在這裏插入圖片描述
連續 ARQ 的注意點:

  1. 同一時刻發送窗口的大小並不一定和接收窗口一樣大。雖然發送窗口的大小是根據接收窗口的大小來設定的,但應答在網絡中傳輸是有時間的,有可能t1時間接收窗口大小爲m,但當確認應答抵達發送者時,接收窗口的大小已經發生了變化。此外發送窗口的大小還隨網絡擁塞情況影響。當網絡出現擁塞時,發送窗口將被調小。
  2. TCP標準並未規定未按序到達的字節的處理方式。但TCP一般都會緩存這些字節,等缺少的字節到達後再交給應用層處理。這比直接丟棄亂序的字節要節約帶寬。
  3. TCP標準規定接收方必須要有累計確認功能。接收方可以對多個TCP報文段同時確認,但不能拖太長時間,一般是0.5S以內。此外,TCP允許接收者在有數據要發送的時候捎帶上確認應答。但這種情況一般較少,因爲一般很少有兩個方向都要發送數據的情況。

流量控制

什麼是流量控制?
如果發送者發送過快,接收者來不及接收,那麼就會有分組丟失。爲了避免分組丟失,控制發送者的發送速度,使得接收者來得及接收,這就是流量控制。

流量控制的目的?
流量控制根本目的是防止分組丟失,它是構成 TCP 可靠性的一方面。

如何實現流量控制?
由滑動窗口協議(連續ARQ協議)實現。
滑動窗口協議既保證了分組無差錯、有序接收,也實現了流量控制。

流量控制引發的死鎖
當發送者收到了一個窗口爲0的應答,發送者便停止發送,等待接收者的下一個應答。但是如果這個窗口不爲0的應答在傳輸過程丟失,發送者一直等待下去,而接收者以爲發送者已經收到該應答,等待接收新數據,這樣雙方就相互等待,從而產生死鎖。

持續計時器
爲了避免流量控制引發的死鎖,TCP 使用了持續計時器。每當發送者收到一個零窗口的應答後就啓動該計時器。時間一到便主動發送報文詢問接收者的窗口大小。若接收者仍然返回零窗口,則重置該計時器繼續等待;若窗口不爲0,則表示應答報文丟失了,此時重置發送窗口後開始發送,這樣就避免了死鎖的產生。

擁塞控制

“擁塞避免”並非指完全能夠避免了擁塞。利用以上的措施要完全避免網絡擁塞還是不可能的。“擁塞避免”是說在擁塞避免階段將擁塞窗口控制爲按線性規律增長,使網絡比較不容易出現擁塞。

擁塞控制 和 流量控制 的區別?

  1. 擁塞控制:擁塞控制是作用於網絡的,它是防止過多的數據注入到網絡中,避免出現網絡負載過大的情況;
  2. 流量控制:流量控制是作用於接收者的,它是控制發送者的發送速度從而使接收者來得及接收。

擁塞控制是針對於網絡而言的,它是防止往網絡中寫入太多分組,從而導致網絡擁塞的情況;而流量控制是針對接收者的,它是通過控制發送者的發送速度保證接收者能夠來得及接收。

擁塞控制的目的?

  1. 緩解網絡壓力
  2. 保證分組按時到達

擁塞控制方法:慢開始(slow-start)、擁塞避免(congestion avoidance)、快重傳(fast retransmit)和快恢復( fast recovery )。

發送方維持一個擁塞窗口 cwnd ( congestion window )的狀態變量。擁塞窗口的大小取決於網絡的擁塞程度,並且動態地在變化。發送方讓自己的發送窗口等於擁塞。

發送方控制擁塞窗口的原則是:只要網絡沒有出現擁塞,擁塞窗口就再增大一些,以便把更多的分組發送出去。但只要網絡出現擁塞,擁塞窗口就減小一些,以減少注入到網絡中的分組數。

慢開始算法 & 擁塞避免算法

慢開始:當主機開始發送數據時,如果立即所大量數據字節注入到網絡,那麼就有可能引起網絡擁塞,因爲現在並不清楚網絡的負荷情況。因此,較好的方法是 先探測一下,即由小到大逐漸增大發送窗口,也就是說,由小到大逐漸增大擁塞窗口數值。通常在剛剛開始發送報文段時,先把擁塞窗口 cwnd(congestion window)設置爲一個最大報文段 MSS(Maximum Segment Size)的數值。而在每收到一個對新的報文段的確認後,把擁塞窗口數值翻倍。用這樣的方法逐步增大發送方的擁塞窗口(cwnd),可以使分組注入到網絡的速率更加合理。
在這裏插入圖片描述
每經過一個傳輸輪次,擁塞窗口 cwnd 就加倍。一個傳輸輪次所經歷的時間其實就是往返時間RTT。不過“傳輸輪次”更加強調:把擁塞窗口cwnd所允許發送的報文段都連續發送出去,並收到了對已發送的最後一個字節的確認。

若發送方出現了超時重傳,則表明網絡出現擁塞。此時:

  • 慢開始門限設爲當前發送窗口的一半
  • 擁塞窗口設爲 1
  • 啓用擁塞避免算法

另外,慢開始的“慢”並不是指cwnd的增長速率慢,而是指在TCP開始發送報文段時先設置cwnd=1,使得發送方在開始時只發送一個報文段(目的是試探一下網絡的擁塞情況),然後再逐漸增大cwnd。

爲了防止擁塞窗口(cwnd)增長過大引起網絡擁塞,還需要設置一個慢開始門限ssthresh狀態變量(如何設置ssthresh)。慢開始門限ssthresh的用法如下:

  • 當 cwnd < ssthresh 時,使用慢開始算法
  • 當 cwnd > ssthresh 時,停止使用慢開始算法而改用擁塞避免算法
  • 當 cwnd = ssthresh 時,既可使用慢開始算法,也可使用擁塞控制避免算法

慢開始算法的作用:慢開始算法將發送窗口從小擴大,而且按指數級擴大,從而避免一開始就往網絡中注入過多的分組從而導致擁塞;它將窗口慢慢擴大的過程其實也在探測網絡擁塞情況的過程,當發現出現擁塞時,及時降低發送速度,從而減緩網絡擁塞。

擁塞避免算法:讓擁塞窗口(cwnd)緩慢地增大,即每經過一個往返時間 RTT 就把發送方的擁塞窗口(cwnd)加 1,而不是加倍。這樣擁塞窗口(cwnd)按線性規律緩慢增長,比慢開始算法的擁塞窗口增長速率緩慢得多。

無論在慢開始階段還是在擁塞避免階段,只要發送方判斷網絡出現擁塞(其根據就是沒有收到確認),就要把慢開始門限ssthresh設置爲出現擁塞時的發送方窗口值的一半(但不能小於2)。然後把擁塞窗口cwnd重新設置爲1,執行慢開始算法。這樣做的目的就是要迅速減少主機發送到網絡中的分組數,使得發生 擁塞的路由器有足夠時間把隊列中積壓的分組處理完畢。

如下圖,用具體數值說明了上述擁塞控制的過程。現在發送窗口的大小和擁塞窗口一樣大。
在這裏插入圖片描述

  • 當TCP連接進行初始化時,把擁塞窗口cwnd置爲1。前面已說過,爲了便於理解,圖中的窗口單位不使用字節而使用報文段的個數。慢開始門限的初始值設置爲16個報文段,即 ssthresh = 16
  • 在執行慢開始算法時,擁塞窗口 cwnd 的初始值爲1。以後發送方每收到一個對新報文段的確認ACK,就把擁塞窗口值翻倍,然後開始下一輪的傳輸(圖中橫座標爲傳輸輪次)。因此擁塞窗口cwnd 隨着傳輸輪次按指數規律增長。當擁塞窗口cwnd增長到慢開始門限值ssthresh時(即當cwnd=16時),就改爲執行擁塞控制算法,擁塞窗口按線 性規律增長
  • 假定擁塞窗口的數值增長到24時,網絡出現超時(這很可能就是網絡發生擁塞了)。更新後的ssthresh值變爲12(即變爲出現超時時的擁塞窗口數值24的一半),擁塞窗口再重新設置爲1,並執行慢開始算法。當 cwnd=ssthresh=12 時改爲執行擁塞避免算法,擁塞窗口按線性規律增長,每經過一個往返時間增加一個MSS的大小

擁塞避免算法的作用:擁塞避免算法使發送窗口以線性方式增長,而非指數級增長,從而使網絡更加不容易發生擁塞。

AIMD算法(加法增大乘法減小算法):慢開始算法 和 擁塞避免算法 還有個名稱叫做加法增大乘法減小算法。

  • 加法增加:指的是擁塞避免算法,使得發送窗口以線性的方式增長;
  • 乘法減小:指的是不管當前正使用慢開始算法還是擁塞避免算法,只要發生擁塞時,慢開始門限將會變成當前窗口的一半。

快重傳算法 & 恢復算法

慢開始算法和擁塞避免算法能保證網絡出現擁塞時進行相應的處理,而快重傳和快恢復是一種擁塞預防的方式,此時網絡可能尚未出現擁塞,但已經有擁塞的徵兆,因此得作出一些預防措施。

如果發送方設置的超時計時器時限已到但還沒有收到確認,那麼很可能是網絡出現了擁塞,致使報文段在網絡中的某處被丟棄。這時,TCP馬上把擁塞窗口 cwnd 減小到1,並執行慢開始算法,同時把慢開始門限值ssthresh減半。這是不使用快重傳的情況。

快重傳原理:因爲TCP具有累計確認的能力,因此接收者收到一個分組的時候不會立即發出應答,可能需要等待收到多個分組之後再同一發出累計確認。但快重傳算法就要求,接收者如果接收到一個亂序的分組的話,就必須立即發出前一個正確分組的確認應答,這樣能讓發送者儘早地知道有一個分組可能丟失。

快重傳算法 首先要求接收方每收到一個失序的報文段後就立即發出重複確認(爲的是使發送方及早知道有報文段沒有到達對方)而不要等到自己發送數據時才進行捎帶確認。
在這裏插入圖片描述
接收方收到了M1和M2後都分別發出了確認。現在假定接收方沒有收到M3但接着收到了M4。顯然,接收方不能確認M4,因爲M4是收到的失序報文段。根據 可靠傳輸原理,接收方可以什麼都不做,也可以在適當時機發送一次對M2的確認。但按照快重傳算法的規定,接收方應及時發送對M2的重複確認,這樣做可以讓 發送方及早知道報文段M3沒有到達接收方。發送方接着發送了M5和M6。接收方收到這兩個報文後,也還要再次發出對M2的重複確認。這樣,發送方共收到了 接收方的四個對M2的確認,其中後三個都是重複確認。快重傳算法還規定,發送方只要一連收到三個重複確認就應當立即重傳對方尚未收到的報文段M3,而不必 繼續等待M3設置的重傳計時器到期。由於發送方儘早重傳未被確認的報文段,因此採用快重傳後可以使整個網絡吞吐量提高約20%。

快重傳算法規定:發送端只要一連收到三個重複的 ACK 即可斷定有分組丟失了,就應該立即重傳丟失的報文段而不必繼續等待爲該報文段設置的重傳計時器的超時。

快恢復原理:當發送者收到同一個分組的三個確認應答後,就基本可以判斷這個分組已經丟失了;這時候無需等待超時,直接執行『乘法減小加法增大』:

  • 將慢開始門限減半
  • 將發送窗口減半(不設爲1)
  • 使用擁塞避免算法

與快重傳配合使用的是快恢復算法,其過程有以下兩個要點:

  1. 當發送方連續收到三個重複確認 ACK 時,就執行“乘法減小”算法,把慢開始門限 ssthresh 減半。這是爲了預防網絡發生擁塞,但接下來不執行慢開始算法。
  2. 由於發送方現在認爲網絡很可能沒有發生擁塞,因此與慢開始不同之處是現在不執行慢開始算法(即擁塞窗口 cwnd 不設置爲1),而是把 cwnd 值設置爲慢開始門限 ssthresh 減半後的數值,然後開始執行擁塞避免算法(“加法增大”),使擁塞窗口緩慢地線性增大。

乘法減小:是指不論在慢開始階段還是擁塞避免階段,只要出現一次超時(即出現一次網絡擁塞),就把慢開始門限值 ssthresh 設置爲當前的擁塞窗口值乘以 0.5。當網絡頻繁出現擁塞時,ssthresh 值就下降得很快,以大大減少注入到網絡中的分組數。

加法增大:是指執行擁塞避免算法後,在收到對所有報文段的確認後(即經過一個往返時間),就把擁塞窗口 cwnd 增加一個 MSS 大小,使擁塞窗口緩慢增大,以防止網絡過早出現擁塞。

快重傳和快恢復的示意圖:新的 TCP Reno 版本在快重傳之後採用快恢復算法而不是採用慢開始算法
在這裏插入圖片描述
在採用快恢復算法時,慢開始算法只是在TCP連接建立時和網絡出現超時時才使用。採用這樣的擁塞控制方法使得TCP的性能有明顯的改進。

也有的快重傳實現是把開始時的擁塞窗口cwnd值再增大一點,即等於 ssthresh + 3 X MSS 。這樣做的理由是:既然發送方收到三個重複的確認,就表明有三個分組已經離開了網絡。這三個分組不再消耗網絡 的資源而是停留在接收方的緩存中。可見現在網絡中並不是堆積了分組而是減少了三個分組。因此可以適當把擁塞窗口擴大了些。

接收方根據自己的接收能力設定了接收窗口rwnd,並把這個窗口值寫入TCP首部中的窗口字段,傳送給發送方。因此,接收窗口又稱爲通知窗口。因此,從接收方對發送方的流量控制的角度考慮,發送方的發送窗口一定不能超過對方給出的接收窗口rwnd 。

發送方窗口的上限值 = Min [ rwnd, cwnd ]

  • 當rwnd < cwnd 時,是接收方的接收能力限制發送方窗口的最大值
  • 當cwnd < rwnd 時,則是網絡的擁塞限制發送方窗口的最大值

相關面試題

1)爲什麼用三次握手?

答: 防止失效的連接請求報文段被服務端接收,從而產生錯誤。如果客戶端發送的連接請求在網絡中滯留太久,客戶端等待一個超時重傳時間後,就會重新請求連接。只要有三次握手,服務器雖然收到了兩個連接請求,並回發了兩個請求確認,但客戶端不會迴應前一個請求確認,就不會打開這個失效的鏈接請求。

失效的連接請求:若客戶端向服務端發送的連接請求丟失,客戶端等待應答超時後就會再次發送連接請求,此時,上一個連接請求就是失效的。

2)爲什麼不能用兩次握手進行連接?

答: 三次握手完成兩個重要的功能,既:1)雙方都知道彼此已準備好,2)允許雙方就初始序列號進行協商,這個序列號在握手過程中進行發送和確認。

如果把三次握手改成兩次握手,可能發生死鎖。比如:客戶端發出去的一個連接請求由於某些原因在網絡節點中滯留導致延遲,直到連接釋放的某個時間點纔到達服務端,但這是一個早已失效的報文,可是這時服務端仍然認爲這是客戶端的建立連接請求第一次握手,於是服務端迴應了客戶端,這是第二次握手。但是客戶端並不會發來新的數據,服務端就這麼傻等着,形成了死鎖。

3)如果已經建立了連接,但是客戶端突然出現故障了怎麼辦?

答: TCP 還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設置爲 2 小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔 75 秒鐘發送一次。若一連發送 10 個探測報文仍然沒反應,服務器就認爲客戶端出了故障,接着就關閉連接。

4)爲什麼用四次揮手?

答: 服務器收到客戶端發送的FIN 連接釋放報文之後,就進入了 CLOSE-WAIT 狀態,發送還未傳送完畢的數據,傳送完畢之後,服務器會發送 FIN 連接釋放報文。

5)爲什麼客戶端要先進入TIME-WAIT狀態,等待2MSL後才進入CLOSED狀態?

答: 爲了保證B能收到A的確認應答。若A發完確認應答後直接進入CLOSED狀態,那麼如果該應答丟失,B等待超時後就會重新發送連接釋放請求,但此時A已經關閉了,不會作出任何響應,因此B永遠無法正常關閉。

6)爲什麼連接的時候是三次握手,關閉的時候卻是四次握手?

答: 因爲當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,“你發的FIN報文我收到了”。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

7)爲什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

答: 雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網絡是不可靠的,有可以最後一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。在Client發送出最後的ACK回覆,但該ACK可能丟失。Server如果沒有收到ACK,將不斷重複發送FIN片段。所以Client不能立即關閉,它必須確認Server接收到了該ACK。Client會在發送出ACK之後進入到TIME_WAIT狀態。Client會設置一個計時器,等待2MSL的時間。如果在該時間內再次收到FIN,那麼Client會重發ACK並再次等待2MSL。所謂的2MSL是兩倍的MSL(Maximum Segment Lifetime)。MSL指一個片段在網絡中最大的存活時間,2MSL就是一個發送和一個回覆所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那麼Client推斷ACK已經被成功接收,則結束TCP連接。

8)UDP 和 TCP 有什麼區別?
在這裏插入圖片描述

  • TCP 向上層提供 面向連接的可靠的服務 ,UDP 向上層提供 無連接的不可靠服務,TCP 保證數據順序,UDP 不保證
  • TCP 傳輸單位稱爲TCP報文段,UDP傳輸單位稱爲用戶數據報
  • 雖然 UDP 並沒有 TCP 傳輸來的準確,但是也能在很多實時性要求高的地方有所作爲。對數據準確性要求高,速度可以相對較慢的,可以選用 TCP
  • TCP對應的協議包括:FTP(文件傳輸協議)、SMTP(郵件傳送協議)、HTTP(從Web服務器傳輸超文本到本地瀏覽器的傳送協議)等。UDP對應的協議包括:DNS(域名解析服務)、SNMP(簡單網絡管理協議)、TFTP(簡單文件傳輸協議)等。

9)在瀏覽器中輸入 www.baidu.com 後的執行過程?用到哪些層?各層是幹什麼的?

瀏覽器要將URL解析爲IP地址,解析域名就要用到DNS協議,首先主機會查詢DNS的緩存,如果沒有就給本地DNS發送查詢請求。DNS查詢分爲兩種方式,一種是遞歸查詢,一種是迭代查詢。如果是迭代查詢,本地的DNS服務器,向根域名服務器發送查詢請求,根域名服務器告知該域名的一級域名服務器,然後本地服務器給該一級域名服務器發送查詢請求,然後依次類推直到查詢到該域名的IP地址。DNS服務器是基於UDP的,因此會用到UDP協議。

得到IP地址後,瀏覽器就要與服務器建立一個http連接。因此要用到http協議,http協議報文格式上面已經提到。http生成一個get請求報文,將該報文傳給TCP層處理,所以還會用到TCP協議。如果採用https還會使用https協議先對http數據進行加密。TCP層如果有需要先將HTTP數據包分片,分片依據路徑MTU和MSS。TCP的數據包然後會發送給IP層,用到IP協議。IP層通過路由選路,一跳一跳發送到目的地址。當然在一個網段內的尋址是通過以太網協議實現(也可以是其他物理層協議,比如PPP,SLIP),以太網協議需要直到目的IP地址的物理地址,有需要ARP協議。

1、客戶端瀏覽器通過 DNS 解析到 www.baidu.com 的 IP 地址 220.181.27.48,通過這個 IP 地址找到客戶端到服務器的路徑。客戶端瀏覽器發起一個 HTTP 會話到 220.181.27.48,然後通過 TCP 進行封裝數據包,輸入到網絡層。
2、在客戶端的傳輸層,把HTTP會話請求分成報文段,添加源和目的端口,如服務器使用80端口監聽客戶端的請求,客戶端由系統隨機選擇一個端口如5000,與服務器進行交換,服務器把相應的請求返回給客戶端的5000端口。然後使用IP層的IP地址查找目的端。
3、客戶端的網絡層不用關心應用層或者傳輸層的東西,主要做的是通過查找路由表確定如何到達服務器,期間可能經過多個路由器,這些都是由路由器來完成的工作,我不作過多的描述,無非就是通過查找路由表決定通過那個路徑到達服務器。
4、客戶端的鏈路層,包通過鏈路層發送到路由器,通過鄰居協議查找給定IP地址的MAC地址,然後發送ARP請求查找目的地址,如果得到迴應後就可以使用ARP的請求應答交換的IP數據包現在就可以傳輸了,然後發送IP數據包到達服務器的地址。

其中,DNS協議,http協議,https協議屬於應用層;TCP/UDP屬於傳輸層;IP協議,ARP協議屬於網絡層。
在這裏插入圖片描述


參考資料:
[1] 計算機網絡傳輸層知識點全覆蓋
[2] TCP/IP詳解–擁塞控制 & 慢啓動 快恢復 擁塞避免
[3] TCP的三次握手與四次揮手理解及面試題(很全面)
[4] 一文搞懂 TCP 和 UDP 的區別

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章