《計算機網路-自頂向下的方法》第三章-運輸層-閱讀筆記

塔希發表於2019-06-03

寫在前面

計算機網路分了五層(應用層,運輸層,網路層,鏈路層,物理層),《自頂向下》的第三章詳細講解了運輸層的兩大協議以及其背後原理,其中tcp協議是本章乃至整個計算機網路的一個重點內容,鑑於此,我覺得有必要對本章作個筆記,以鞏固運輸層的知識。

正文

運輸層的目的在於為不同主機(host)上的應用或者說程式提供邏輯通訊——通過運輸層協議,兩臺電腦彷彿直接相連一樣。應用無需知道底層內部實現的原理和細節,比如怎麼把遠隔世界兩地電腦上的資料進行相互傳輸。

本章的一些注意點:

  • 運輸層協議僅僅實現在網路的邊緣處,例如主機,電腦,手機等。如路由器,交換機這些網路核心裝置,是沒有實現運輸層協議的
  • 每一層協議僅僅檢查分組相應的協議層欄位
  • 最常用的兩種輸入層協議,tcp和udp
  • 運輸層的下面是網路層,網路層的目的在於為不同的主機提供邏輯通訊,而非主機上的程式
  • 網路層常用協議是IP,其提供的是一種不可靠的資料傳輸服務
  • 為了做到為不同主機(host)上的應用或者說程式提供邏輯通訊這一目的,運輸層協議必須能分辨出資料的來源和去向。為此,運輸層存在著兩種行為,多路複用和多路分解

多路複用

當運輸層收到來自上方應用層的資料時,運輸層會為資料封上一些頭部資訊,根據所有協議不同,封上的資訊也不一樣。這一行為,被稱為多路複用。

多路分解

當運輸層收到下方網路層傳輸來的資料時,運輸層會檢查多路複用時封上的資訊,從而正確的把資料定向到相應的程式。

如何使用運輸層的協議? 作業系統提供了被稱為socket的介面api供程式設計人員呼叫,對socket的形象理解是其是一種抽象,將複雜的實現(tcp, udp)協議的各種行為抽形成簡單的幾個函式給開發人員使用。就像瀏覽器將傳送請求報文這一http協議規定的行為,抽象成我們只需要輸入url然後回車即可。

這裡需要注意的一點是,在一般情況下,一個計算機埠只能被一個程式佔用。一個程式可以建立多個socket,多個tcp socket可以監聽同一個埠,並保證接受的資料依舊是正確的。但多個udp socket就無法監聽同一埠。這其中的差異源於tcp和udp協議的不同,tcp是面向連線的,其有足夠狀態的資訊來分辨資料來源,後定向到正確的socket。但udp不需要維持連線,僅僅通過埠號來決定資料的去向,所以會導致衝突。

udp的多路複用和分解

一個udp socket通過一個二元組(目的ip地址,目的埠號)來標識,當輸入層收到資料時,通過檢查這個二元組,來定向資料該去往哪一個udp socket。這也是為什麼多個udp socket無法監聽同一個埠的原因,因為系統無法再根據二元組來確定訊息的去向(它們的二元組是一樣的)。

TCP的多路複用分解

一個tcp socket通過一個四元組(源ip,源埠,目的ip,目的埠號)來標識,這也解釋為什麼多個tcp socket可以監聽同一個埠,儘管目的ip和目的埠號是一樣的,但是源ip和源埠的組合總是不同的。

UDP

相比於TCP來講,UDP是一個簡單的協議,就是把網路層IP提供的服務封裝了下,實現了多路複用和分解,提供了端到端程式間的通訊和錯誤檢驗服務。

相對於TCP來說:

  • UDP是不可靠的傳輸服務
  • 沒有流量和擁塞控制

但:

  • 能夠夠精細的控制資料的傳送時間和速率
  • 無需事先建立連線
  • 無連線狀態
  • 分組首部開銷小

封裝

在接收到應用層傳輸來資料後,在資料前方加上了四個欄位,分別是源埠號、目的埠號、長度(包括頭部)、檢驗和,應用資料。

可靠資料傳輸

資料傳輸可能遇到的問題:

  • 傳輸中資料被損壞
  • 資料丟失
  • 資料可能亂序到達

解決方法:

  • 檢驗和
  • 序號
  • 定時器
  • 肯定和否定反饋分組

如何在保證可靠性的前提下,提高其效能?

  • 通過引入流水線(pipelining)技術

引入流水線導致了:

  • 序號範圍需要增加
  • 收發雙方可能需要快取亂序到達的分組
  • 以上兩個的具體實現取決於傳輸協議如何處理分組丟失、損壞的問題(是選擇回退N步,還是選擇重傳)

回退N步

其核心在於,傳送方會維持一個視窗,傳送方能傳送的資料量取決於視窗長度,並且當丟失時會重送所有未確認的分組。

接收方會丟棄亂序到達的快取

特點:

  • 累計性ACK
  • 單一定時器

選擇重傳

核心在於,收發雙方都會維持一個視窗,並且盡力保證視窗的狀態是同步的,因此當分包丟失時,傳送方只會重送丟失的分組。

接收方會快取亂序到達的分組

特點:

  • 獨立性ACK
  • 多個定時器

TCP

特點:

  • 面向連線
  • 全雙工的
  • 點對點,不存在一次傳送將資料傳遞給多個接收方、
  • 在合適的時候傳送 傳送快取 裡的資料
  • 為每個資料封上一個TCP頭部
  • TCP連線的每一端都具有傳送快取和接受快取

報文段結構

  • 源埠號

  • 目的埠號

  • 序號(seq) - 所帶資料的第一個位元的序號,同時也是接收方期待的序號,等於接收方回覆報文中的ACK(n)中的n

  • 確認號(ACK) - 對於一個ACK(n)來說,告訴對方n-1前的資料已經收到,下一次期待的序列號為n

  • 首部長度

  • URG

  • ACK - 指示,用於指示報文中確認號欄位的值是有效的

  • PSH - 指示,立即傳送傳送快取裡的資料

  • RST - 指示,用於強制關閉連線

  • SYN - 指示,用於握手階段也就是建立連線的階段

  • FIN - 指示,用於正常關閉連線

  • 接受視窗 - 用於TCP的流量控制功能

  • 因特網檢驗和

  • 緊急資料指標

  • 選項

  • 應用資料

可靠資料傳輸

  • TCP協議為資料的每一Byte都編號,而非針對報文段
  • 總是維持最老未經確認的1 Byte的計時器
  • 每一次超時重置的計時器時間會加倍
  • 其錯誤恢復機制是回退N步和選擇重傳的混合體
    • 不會丟棄亂序到達的分組,而是快取起來
    • 採用累計性ACK
    • 只會重傳丟失報文段中的資料

快速重傳

當連續收到4個相同的ACK時(一個正常的ACK,三個正常ACK的重複),會觸發快速重傳,立即重發分組

流量控制

為了防止過高資料流量導致接收者的接受快取爆掉,接收者會在其tcp報文中通過 接受視窗 指示發收者還能傳送多少資料

接受視窗(rwnd)公式:

  • rwnd = RcvBuffer - [LastByteRead - LastbyteRead]
  • 且:LastByteSent - LastByteAcked <= rwnd

TCP連線管理

建立連線(三次握手)

  1. 客戶端傳送SYN位置1的報文段
  2. 服務端返回SYN為1,ACK為1的報文段
  3. 客戶端傳送ACK為1,且附帶資料的報文段

斷掉連線

  1. 客戶傳送FIN為1的報文段
  2. 服務端返回ACK為1的報文段
  3. 服務端傳送FIN為1的報文段
  4. 客戶端返回ACK為1的報文段
  5. 客戶端在一段時間後,關閉連線

擁塞控制

擁塞的代價

  • 導致分組過長的排隊時延
  • 需要重傳因快取溢位丟失的分組
  • 高延時導致重送分組
  • 丟包導致運輸相關分組的分組交換器所作的工作全部白費

TCP的擁塞控制

TCP採用端到端的擁塞控制

三個主要問題:

  1. 一個TCP的傳送方如何限制自己的傳送流量的速率?

通過設定一個擁塞視窗(cwnd),並且保證:LastByteSent - LastByteAcked <= min{cwnd, rwnd}

  1. 如何感知其傳送路徑擁塞了?
  • timeout
  • 收到一次正常ACK後連續收到三次正常ACK的重複
  1. 感到擁塞時,採用什麼樣的演算法改變傳送速率?
  • 慢啟動

cwnd的值從1 MSS開始,並且對每一個ACK,cwnd值變為原來的2倍,直到超過閾值(ssthresh),轉為擁塞避免模式

  • 擁塞避免

在每一個RRT時間,cwnd的值增加一個MSS

  • 快速恢復

cwnd的值降為一半加上重複收到的重複ACK的數量,並且每一個ACK,cwnd的值增加一個MSS

在實踐中,一旦timeout就會會到慢啟動的狀態,多次重複ACK則會進入快速恢復狀態

TCP公平

TCP的公平性在於保證每個連線的吞吐量是平均的,而不是應用或程式間。

相關文章