協議簇:TCP 解析:TCP 數據傳輸

簡介

前面,我們分別介紹了 TCP 基礎知識以及連接的建立和關閉,以及最重要的 Sequence Number 的概念. 本篇文章,我們來介紹一下 TCP 如何傳輸數據.

系列文章

協議簇:TCP 解析:基礎
協議簇:TCP 解析:建立連接
協議簇:TCP 解析:連接斷開
協議簇:TCP 解析:Sequence Number
協議簇:TCP 解析:數據傳輸

數據傳輸

當一個 TCP 連接建立成功之後, TCP 段便可以在這條連接上雙向傳輸. 由於底層網絡的不穩定,TCP 段可能在傳輸過程中出錯,TCP 協議會重傳這些出錯的 TCP 段以確保每個段都成功的發送到了對方. 這個過程依賴於 Sequence Number 機制, TCP雙方都需要維護一系列連接狀態信息,以確保 Sequence Number 機制正常工作.

發送方使用 SND.NXT 字段記錄下一個可用的 SEQ. 發送方將使用 SND.NXT 的值作爲下一個發送的 TCP 段的 SEQ; 接收方使用 RCV.NXT 字段記錄下一個應該收到的 TCP 段的 SEQ 值。發送方使用 SND.UNA 記錄最早的已發送但還沒有收到確認的 SEQ 值。 當所有數據包被成功發送並收到接收方的ACK時且當前網絡空閒, SND.NXT, SND.UNA, RCV.NXT 三個字段的值應該是相同的.

當發送方構建了一個 TCP段並將它發送出去時, 發送方應該增加 SND.NXT 值。 當接收方接收到一個 TCP段時,接收方應該增加 RCV.NXT 併發送相應的 ACK. 當發送方接收到ACK 時,它應該增加 SND.UNA. 增加的幅度等於相應 TCP 段中所包含數據的長度. 注意,從連接建立成功之後,所有的段都應該包含 ACK 信息.

重傳超時時間

TCP 會重傳那些已經發送,但是一定時間之後還未收到ACK的段. 但是這個“一定時間”的大小的選擇非常重要. 如果選擇的太小,容易導致鏈接上充斥着冗餘的數據(已經發送但是由於網絡慢還未到達對方,但是發送方卻由於重傳超時時間已經到達,所以重發該段。 最終接收方會收到兩個一摸一樣的數據)。 如果太大,又會導致失敗的數據包在失敗之後等待很長時間才能被重傳. 這種i情況下的結果是一樣的,那就是 TCP 數據傳輸效率低下.

由於組成網絡的物理鏈路形形色色,因此,沒有一個固定的值能在各種情況下完美工作. 因此,這個超時時間應該是動態變化的.

RFC 中介紹了一種方案. 該方案如下:

發送數據,然後等待對應的 ACK,記錄這個過程中所需要的時間。 我們稱它爲 Round Trip Time(RTT).
接着,使用 RTT 計算 Smoothed Round Trip Time(SRTT),計算方法如下:
SRTT=(ALPHASRTT+((1ALPHA)RTT) SRTT = ( ALPHA * SRTT) + ((1 - ALPHA) * RTT)
然後,使用更新之後的 SRTT 值計算 RTO(Retransmission timeout)的值,計算方法如下:
RTO=min[UBOUND,max[LBOUND,(BETASRTT)]] RTO = min [ UBOUND, max [ LBOUND, ( BETA * SRTT ) ] ]
其中,
UBOUND 和 LBOUND 分別代表超時時間的上限和下限.
ALPHA 是平滑因子(smoothing factor, 比如, 0.8 - 0.9)
BETA 是延遲方差因子 (delay variance factor, 比如, 1.3 - 2.0)

窗口的控制

每個 TCP 段中都包含 Window 字段來通知對方當前接收方能接收的 SEQ 的範圍.

使用一個較大的 Window 值,對方會發送更多的數據給接收方。 但是如果太多數據被髮送過來,那麼這些數據會被丟棄. 這種情況下,會導致額外的重傳工作, 增大物理鏈路的負擔; 使用一個較小的 Window 值,將會抑制發送發的發送速率,會導致傳輸速率低下。

當發送窗口爲 0 的時候,發送方應該週期性的給接收方重傳數據. RFC 中建議在這種情況下使用 2 分鐘作爲重傳超時時間. 這種情況下的重傳的意義是: 確保當接收方又可以接收數據的時候,這個狀態能被通告給發送方。

當接收方的窗口大小爲 0 時,接收到對方的TCP段後,必須回覆相應的ACK, 這個ACK中包含接收方期待接收的 SEQ 值和窗口爲 0 的信息.

窗口大小的控制嚴重的影響着 TCP 連接的數據傳輸效率。 RFC 中提出了一些建議:

  1. 較小的窗口值會影響發送效率。 因此,建議接收方延遲更新窗口,直到附加分配的大小達到
    最大可能分配大小的 X % (x 的值爲 20 - 40)

  2. 建議發送發儘量避免發送太小的段,而應該等到窗口的大小足夠了再發送。 但是如果上層用戶調用 了 push 接口, 此時應該直接發送數據而不必顧慮段的大小。

    注意, ACK 段應該總是被立即發送,不應該被推遲。

  3. TCP實現應該總是嘗試使用大一些的窗口值

總結

至此, RFC 793 中描述的 TCP 介紹完畢。 這裏忽略了接口定義的描述.

相關文章:
協議簇:TCP 解析:基礎
協議簇:TCP 解析:建立連接
協議簇:TCP 解析:連接斷開
協議簇:TCP 解析:Sequence Number

後續,我們會介紹更加直白的TCP,而不再基於 TCP 的規範。

END!

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