【計算機網絡】—— TCP保證可靠傳輸和提高網絡利用率

TCP如何保證可靠傳輸

TCP通過檢驗和、序列號、確認應答、重發控制、連接管理以及窗口控制等機制來實現可靠性傳輸

確認應答(ACK)機制

  • 正常數據傳輸,若接收方收到了發送方的數據,就會返回一個ACK響應確認已經收到
    正常數據傳輸
  • TCP將每個字節的數據都進行了編號,即爲序列號,每個ACK都帶有對應的確認序號,意思是告訴發送方,我已經收到了哪些數據,下一次你應該從哪裏開始發。
    序列號

超時重傳

  • 主機A發給主機B的數據,可能會由於網絡擁塞等原因,使得主機B未收到數據,丟包的情況
  • 如果主機A在一定時間間隔內未收到主機B的應答,就會將數據重發
    超時重傳

但是如果情況是主機B收到了數據,但是返回的ACK包丟失了,導致主機A爲收到應答呢?
丟包
上述情況主機B會收到重複的數據那麼TCP協議需要能夠識別出那些包是重複的包, 並且把重複的丟棄掉.這時候我們可以利用前面提到的序列號, 就可以很容易做到去重的效果,這就是TCP協議的去重機制,也是保證TCP傳輸可靠性的機制。

確認重發時間

重發時間

  • 最理想的情況下, 找到一個最小的時間, 保證 “確認應答一定能在這個時間內返回”.
  • 但是這個時間的長短, 隨着網絡環境的不同, 是有差異的.
  • 如果超時時間設的太長, 會影響整體的重傳效率;
  • 如果超時時間設的太短, 有可能會頻繁發送重複的包;

TCP爲了保證無論在任何環境下都能比較高性能的通信, 因此會動態計算這個最大超時時間.

  • Linux中(BSD Unix和Windows也是如此), 超時以500ms爲一個單位進行控制, 每次判定超時重發的超時時間都是500ms的整數倍.
  • 如果重發一次之後, 仍然得不到應答, 等待 2*500ms 後再進行重傳.
  • 如果仍然得不到應答, 等待 4*500ms 進行重傳. 依次類推, 以指數形式遞增.
  • 累計到一定的重傳次數, TCP認爲網絡或者對端主機出現異常, 強制關閉連接

連接管理機制

  • TCP與UDP不同,它是面向連接的,TCP連接的建立與斷開至少要來回發送7個數據包纔可能完成
    握手與揮手

流量控制

接收端處理數據的速度是有限的. 如果發送端發的太快, 導致接收端的緩衝區被打滿, 這個時候如果發送端繼續發送,就會造成丟包, 繼而引起丟包重傳等等一系列連鎖反應.
因此TCP支持根據接收端的處理能力, 來決定發送端的發送速度. 這個機制就叫做流量控制(Flow Control);

  • 接收端將自己可以接收的緩衝區大小放入 TCP 首部中的 “窗口大小” 字段, 通過ACK端通知發送端;
  • 窗口大小字段越大, 說明網絡的吞吐量越高;
  • 接收端一旦發現自己的緩衝區快滿了, 就會將窗口大小設置成一個更小的值通知給發送端;
  • 發送端接受到這個窗口之後, 就會減慢自己的發送速度;
  • 如果接收端緩衝區滿了, 就會將窗口置爲0; 這時發送方不再發送數據, 但是需要定期發送一個窗口探測數據段, 使接收端把窗口大小告訴發送端
    流量控制

擁塞控制

雖然TCP有了滑動窗口這個大殺器, 能夠高效可靠的發送大量的數據. 但是如果在剛開始階段就發送大量的數據, 仍然可能引發問題.
因爲網絡上有很多的計算機, 可能當前的網絡狀態就已經比較擁堵. 在不清楚當前網絡狀態下, 貿然發送大量的數據,是很有可能引起雪上加霜的.
TCP引入 慢啓動 機制, 先發少量的數據, 探探路, 摸清當前的網絡擁堵狀態, 再決定按照多大的速度傳輸數據;
擁塞控制

  • 此處引入一個概念程爲擁塞窗口
  • 發送開始的時候, 定義擁塞窗口大小爲1;
  • 每次收到一個ACK應答, 擁塞窗口加1;
  • 每次發送數據包的時候, 將擁塞窗口和接收端主機反饋的窗口大小做比較, 取較小的值作爲實際發送的窗口;

像上面這樣的擁塞窗口增長速度, 是指數級別的. “慢啓動” 只是指初使時慢, 但是增長速度非常快.

  • 爲了不增長的那麼快, 因此不能使擁塞窗口單純的加倍.
  • 此處引入一個叫做慢啓動的閾值
  • 當擁塞窗口超過這個閾值的時候, 不再按照指數方式增長, 而是按照線性方式增長
    擁塞控制

提高網絡利用率

滑動窗口

按照我們之前的說法,TCP在傳輸數據的是發一次數據,給一個應答,就會出現下圖所示的情況,那如果一個報文很長的話,這樣包往返的時間很長,網絡吞吐量就會很差。
正常傳輸數據
既然這樣一發一收的方式性能較低, 那麼我們一次發送多條數據, 就可以大大的提高性能(其實是將多個段的等待時間重疊在一起了)
滑動窗口

  • 窗口大小指的是無需等待確認應答而可以繼續發送數據的最大值. 上圖的窗口大小就是4000個字節(四個段).
  • 發送前四個段的時候, 不需要等待任何ACK, 直接發送;
  • 收到第一個ACK後, 滑動窗口向後移動, 繼續發送第五個段的數據; 依次類推;
  • 操作系統內核爲了維護這個滑動窗口, 需要開闢 發送緩衝區 來記錄當前還有哪些數據沒有應答;
  • 只有確認應答過的數據, 才能從緩衝區刪掉;
  • 窗口越大, 則網絡的吞吐率就越高;

滑動窗口

  • 有了滑動窗口機制,可以無需等待應答,直接發送數據
  • 滑動窗口其實是TCP發送緩衝區中的一部分
  • 滑動窗口的大小是由接收方接收緩衝區的大小決定的,在雙方第一次通信時,發送方就會通過報文確定接收方接收緩衝區的大小

延遲應答

如果接收數據的主機立刻返回ACK應答, 這時候返回的窗口可能比較小.

  • 假設接收端緩衝區爲1M. 一次收到了500K的數據; 如果立刻應答, 返回的窗口就是500K;
  • 但實際上可能處理端處理的速度很快, 10ms之內就把500K數據從緩衝區消費掉了;
  • 在這種情況下, 接收端處理還遠沒有達到自己的極限, 即使窗口再放大一些, 也能處理過來;
  • 如果接收端稍微等一會再應答, 比如等待200ms再應答, 那麼這個時候返回的窗口大小就是1M;

一定要記得, 窗口越大, 網絡吞吐量就越大, 傳輸效率就越高. 我們的目標是在保證網絡不擁塞的情況下儘量提高傳輸效率; 那麼所有的包都可以延遲應答麼? 肯定也不是;

  • 數量限制: 每隔N個包就應答一次;
  • 時間限制: 超過最大延遲時間就應答一次;

具體的數量和超時時間, 依操作系統不同也有差異; 一般N取2, 超時時間取200ms;
延遲應答

捎帶應答

在延遲應答的基礎上, 我們發現, 很多情況下, 客戶端服務器在應用層也是 “一發一收” 的. 意味着客戶端給服務器說了 “How are you”, 服務器也會給客戶端回一個 “Fine, thank you”;
那麼這個時候ACK就可以搭順風車, 和服務器迴應的 “Fine, thank you” 一起回給客戶端
捎帶應答

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