關於 TCP 需要了解的事兒

騎摩托馬斯發表於2018-09-03

TCP 的特點

TCP 是面向連線的、可靠的流協議。 TCP 為提供可靠的傳輸,實行“順序控制”或“重發控制”機制。此外還具備“流量控制”、“擁塞控制”、提供網路利用率等眾多功能。

TCP在網路OSI的七層模型中的第四層——Transport層,IP在第三層——Network層,ARP在第二層——Data Link層,在第二層上的資料,我們叫Frame,在第三層上的資料叫Packet,第四層的資料叫Segment

資料首先會打到TCP的Segment中,然後TCP的Segment會打到IP的Packet中,然後再打到乙太網Ethernet的Frame中,傳到對端後,各個層解析自己的協議,然後把資料交給更高層的協議處理

TCP 可靠性傳輸

關於 TCP 需要了解的事兒

上圖就是 TCP 建立通訊示意圖,包含了著名的三次握手和四次揮手。

在 TCP 中,通過序列號 (SYN) 與確認應答 (ACK) 提供可靠性,當傳送端的資料到達接收主機時,接收端主機會返回一個已收到訊息的通知,這個訊息叫做確認應答 (ACK)

為什麼建連結要3次握手,斷連結需要4次揮手

  • 對於建連結的3次握手,主要是要初始化Sequence Number 的初始值。通訊的雙方要互相通知對方自己的初始化的Sequence Number(縮寫為ISN:Inital Sequence Number)——所以叫SYN,全稱Synchronize Sequence Numbers。也就上圖中的 x 和 y。這個號要作為以後的資料通訊的序號,以保證應用層接收到的資料不會因為網路上的傳輸的問題而亂序(TCP會用這個序號來拼接資料)
  • 對於4次揮手,其實你仔細看是2次,因為TCP是全雙工的,所以,傳送方和接收方都需要Fin和Ack。只不過,有一方是被動的,所以看上去就成了所謂的4次揮手。

上圖演示的是一種理想狀態下的 TCP 連線過程,但是現實中的連線過程可能並沒有那麼順利,可能會出現丟包的情況。這就需要 TCP 的重發機制來保證資料的可靠性傳輸。

丟包包括兩種情況,一種是資料在到達接收端的過程中就發生了丟失,另外一種是接收端接受到了資料,但是確認應答在返回的途中發揮了丟失。

上述這些確認應答處理、重發控制以及重複控制等功能都可以通過序列號實現。序列號是安順序給傳送資料的每一個位元組(8 位位元組)都標上號碼的編號。接收端查詢接收資料 TCP 首部中的序列號和資料的長度,將自己下一步應該接收的序號作為確認應答反送回去。接這樣通過序列號和確認應答號,TCP 可以實現可靠傳輸

關於 TCP 需要了解的事兒

利用視窗控制提高速度

TCP 以 1 個段為單位,即 MSS(Maximum Segment Size) 最大訊息長度,進行資料傳輸。MSS 是在三次握手的時候,在兩端主機之間被計算出來的,三次握手的時候會在 TCP 的首部中寫入 MSS 選項,告訴對方自己的介面能夠適用的 MSS 大小。然後在兩者之間選擇一個較小的值投入使用。

TCP 在資料傳輸中,每發一個段進行一次確認應答的處理。這樣的傳輸方式有一個缺點。那就是,包的往返時間越長通訊效能就越低。

為了解決這個問題,TCP 引入了視窗的概念。確認應答不再是以每個分段,而是以更大的單位進行確認,也就是說,傳送段主機,在傳送了一個段以後不必要一直等待確認應答,而是繼續傳送。

關於 TCP 需要了解的事兒

視窗大小就是指無需等待確認應答而可以繼續傳送資料的最大值。這個機制實現了通過使用大量的緩衝區,來對多個段同時進行確認應答的功能。

關於 TCP 需要了解的事兒

視窗控制與重發控制

確認應答未能返回情況

在這種情況下,資料已經到達對端,是不需要再進行重發的。然而,在沒有使用視窗控制的時候,沒有收到確認應答的資料都會被重發。而使用了視窗控制,某些確認應答即便丟失也無需重發。

關於 TCP 需要了解的事兒

如上圖所示,即使 3001 和 4001 的確認應答在返回途中丟失了,但是客戶端收到了 5001 的確認應答,則客戶端會繼續傳送下面的資料而不會進行重發。

報文段丟失

關於 TCP 需要了解的事兒

如上圖所示,當發生某個報文段丟失後,傳送段會一直收到序列號為 1001 的確認應答,因此在視窗比較大,又出現報文段丟失的情況下,同一個序號的確認應答將會被重複不斷的返回。而傳送段主機如果連續 3 次收到同一個確認應答,就會將其所對應的資料進行重發。這種機制幣之前提到的超時管理更加高效,因此也被稱作高速重發控制

流控制

TCP 提供一種機制可以讓傳送端根據接收端的實際接收能力控制傳送的資料流。這就是所謂的流控制。它的具體操作是接收端主機向傳送端主機通知自己可以接收資料的大小,於是傳送端會傳送不超過這個限度的資料。該大小限度就是上面提到的視窗的大小。

TCP 首部中,專門有一個欄位來通知視窗大小。接收主機將自己可以接收的緩衝區大小放入這個欄位中通知給傳送端。這個欄位越大,說明網路吞吐量越高。

關於 TCP 需要了解的事兒

如圖所示,當接收端收到從 3001 號開始的資料斷後其緩衝區即滿,不得不暫時停止接收資料。之後,在收到傳送視窗更新通知後通訊才得以繼續進行。

擁塞控制

為了防止在通訊剛開始時傳送大量資料,引起網路擁堵的情況,TCP 在通訊一開始時就會通過一個叫慢啟動的演算法算出數值,對傳送資料進行控制。

關於 TCP 需要了解的事兒

首先,為了在傳送端調節所需傳送資料的量,定義了一個叫“擁塞視窗”的概念。在慢啟動的時候,將這個擁塞視窗的大小設定為 1 個資料段 (1 MSS),之後每收到一次確認應答,擁塞視窗的值就加 1。在傳送資料包時,將擁塞視窗的大小與接收端主機通知的視窗大小做比較,然後按照它們當中較小的值,傳送比其還要小的資料量。

TCP頭格式

我們來看一下TCP頭的格式

TCP頭格式

需要注意這麼幾點:

  • TCP的包是沒有IP地址的,那是IP層上的事。但是有源埠和目標埠。
  • 一個TCP連線需要四個元組來表示是同一個連線(src_ip, src_port, dst_ip, dst_port)準確說是五元組,還有一個是協議。但因為這裡只是說TCP協議,所以,這裡我只說四元組。
  • Sequence Number是包的序號,用來解決網路包亂序(reordering)問題。
  • Acknowledgement Number就是ACK——用於確認收到,用來解決不丟包的問題。
  • Window又叫Advertised-Window,也就是著名的滑動視窗(Sliding Window),用於解決流控的。
  • TCP Flag ,也就是包的型別,主要是用於操控TCP的狀態機的。

參考

相關文章