1. 程式人生 > >TCP的交互數據流

TCP的交互數據流

收集數據 不可靠 src 應用 隨機 TCP/IP 每次 雙工 引入

在TCP進行數據傳輸時,可以分為成塊數據流和交互數據流兩種,如果按字節計算,成塊數據與交互數據的比例約為90%和10%,TCP需要同時處理這兩類數據,且處理的算法不同。

書籍本章中以Rlogin應用為例觀察交互數據的傳輸過程。提示經受時延的確認是如何工作以及Nagle算法怎樣減少了通過廣域網絡傳輸的小分組的數目。

交互式輸入

技術分享圖片

經受時延的確認
上圖第二,三個報文段可以合並---按鍵確認和按鍵回顯一起發送。這種技術叫做經受時延的確認。
通常TCP在接收到數據時並不立即發送ACK,相反,它推遲發送,以便將ACK與需要沿該方向發送的數據一起發送(有時這種現象為數據捎帶的ACK)。絕大數實現采用的時延為200ms,也就是說,TCP將以最大200ms的時延等待是否有數據一起發送。

ACK延時等待時間不大於TCP定時器的原因:
假如TCP使用200ms的定時器,該定時器將相對於內核引導的200ms固定時間溢出,由於將要確定的數據隨機到達,TCP將在下一次內核的200ms定時器溢出時得到通知,所以ACK實際等待的時間為1~200ms中任一刻。

Nagle算法
Nagle算法要求TCP連接上最多只有一個未被確認的未完成小分組,在該分組確認到達之前不能發送其他的小分組。相反,TCP收集這些少量的分組,並在確認到達時以一個大的分組發出去。

流程:
(1)發送端TCP將從應用進程接收到的第一數據塊立即發送,不管其大小,哪怕只有一個字節。
(2)發送端輸出第一塊數據後開始收集數據,並等待確認。

(3)確認未達到時,若收集數據達到窗口的一半或一個MSS段,立即發送。
(4)確認到達後,把緩沖區中的數據組成一個TCP段,然後發送。

TCP的成塊數據流

1.滑動窗口協議

TCP滑動窗口的可視化表示

技術分享圖片

我們將字節從1到11進行標號,接收方通告的窗口稱為提供的窗口,它覆蓋了第4字節到第9字節的數據,且通告窗口大小為6。發送方計算接收者的可用窗口,以便確定有多少數據可以被立即發送。當接收方確認數據後,這個滑動窗口向右移動。窗口兩個邊沿的相向運動有以下3種情況: (1)在數據被發送和確認時,窗口左邊沿向右邊沿靠近,稱為窗口合攏。 (2)在另一端接收進程讀取已經確認的數據並釋放了TCP接收緩存時,窗口右邊沿向右移動,稱為窗口張開,此時允許發送更多的數據。
(3)當右邊沿向左移動時,稱為窗口收縮。這種方式不被建議。 技術分享圖片

2.窗口大小

接收方的窗口大小通常可以由接收進程控制,這將影響TCP的性能。對於以太網來說,默認的4096字節並不是最理想的大小,提高窗口的大小 有時 可以提高網絡的吞吐量。 理解窗口 IP層協議屬於不可靠的協議,IP層並不關心數據是否發送到了對端,TCP通過確認機制來保證數據傳輸的可靠性,在比較早的時候使用的是send–wait–send的模式,其實這種模式叫做stop-wait模式,發送數據方在發送數據之後會啟動定時器,如果數據或者ACK丟失,那麽定時器到期之後,收不到ACK就認為發送出現狀況,要進行重傳,這樣就會降低了通信的效率。
為了優化上述問題,比如我讓發送的每一個包都有一個ID,接收端必須對每一個包進行確認,這樣設備A一次多發送幾個片段,而不必等候ACK,同時接收端也要告知它能夠收多少,這樣發送端發起來也有個限制,當然還需要保證順序性,不要亂序,對於亂序的狀況,我們可以允許等待一定情況下的亂序,比如說先緩存提前到的數據,然後去等待需要的數據,如果一定時間沒來就丟棄掉,來保證順序性。在TCP/IP協議棧中,滑動窗口的引入可以解決此問題。
發送方發送窗口和接收端接收窗口一一對應,告訴接收端接收區緩存是多少。

理解前提
1、“窗口”對應的是一段可以被發送者發送的字節序列,其連續的範圍稱之為“窗口”。
2、 “滑動”則是指這段“允許發送的範圍”是可以隨著發送的過程而變化的,方式就是按順序“滑動”。在引入一個例子來說這個協議之前,我覺得很有必要先了解以下前提:

    • TCP協議的兩端分別為發送者A和接收者B,由於是全雙工協議,因此A和B應該分別維護著一個獨立的發送緩沖區和接收緩沖區,由於對等性(A發B收和B發A收),我們以A發送B接收的情況作為例子;
    • 發送窗口是發送緩存中的一部分,是可以被TCP協議發送的那部分,其實應用層需要發送的所有數據都被放進了發送者的發送緩沖區;
    • 發送窗口中相關的有四個概念:已發送並收到確認的數據(不再發送窗口和發送緩沖區之內)、已發送但未收到確認的數據(位於發送窗口之中)、允許發送但尚未發送的數據以及發送窗口外發送緩沖區內暫時不允許發送的數據;
    • 每次成功發送數據(發送且收到了ACK)之後,發送窗口就會在發送緩沖區中按順序移動,將新的數據包含到窗口中準備發送;

3.PUSH標誌

發送方使用該標誌通知接收方將所收到的數據全部提交給接收進程,這裏的數據包括與PUSH一起傳送的數據 以及 接收方TCP已經為接收進程收到的其他數據。 特點: (1)通過設置PUSH標誌,客戶進程通知TCP在向服務器發送一個報文段時不要因等待額外數據而使已提交數據在緩存中滯留。 (2)當服務器接收到設置了PUSH標誌的報文段時,它需要立即將這些數據提交給服務器進程而不能等待判斷是否還會有額外數據到達。 (3)如果待發送數據將清空發送緩存,則自動設置PUSH標誌(大多數源自伯克利的實現)。

慢啟動:

前邊的TCP連接,可以看到,當連接建立後,發送端總是一下發送好幾個分組過去,直至達到接收方的通告窗口大小為止。
當然這種策略在局域網中,幾乎沒有什麽問題。但是如果發送方和接收方之間是一個存在著多個路由器和速率較慢的鏈路時,這就可能出現擁塞的問題...
TCP需要支持一種慢啟動的算法。顧名思義,是一點點加速,而不是一次傳太多過去。
實現原理:發送方需要支持一個窗口,擁塞窗口(congestion window,cwnd)。當TCP連接建立好以後,擁塞窗口被初始化為1個報文段,發送端每收到ACK,就在cwnd中增加報文段(比如說這個ACK是確認的一個報文段,那麽我就增加一個報文段;下次我就發倆報文段,收到這倆的ACK後,我就增加到4個報文段長度。有點類似於成倍增加,這就是慢啟動)。那麽現在有兩個窗口了,發送端傳數據的時候是用擁塞窗口大小還是接收端的通告窗口大小呢?這裏是取兩者中較小的一個大小。

TCP的交互數據流