歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> TCP滑動窗口和流控

TCP滑動窗口和流控

日期:2017/2/27 15:55:25   编辑:Linux教程

TCP的滑動窗口是一個很重要的概念,也是很晦澀的一個知識點。下面就大概介紹下TCP滑動窗口為什麼出現?它是怎麼工作的的?

什麼是TCP窗口

首先,要理解,client和server各自協議棧都有自己的buffer,應用層讀寫數據的源都是協議棧buffer裡。以接收端為例,應用程 序調用read()時,會從buffer裡移走數據到用戶空間,應用程序讀的速度越快(read(1024)必然比read(1)要快),那麼 buffer裡的內容消費的越快,buffer也會越空。那麼TCP就可以告訴client,我現在很閒,你可以發送更多的數據來。"更多"是多少?這就 說窗口,窗口就是量化接收端和服務端當前能處理數據的能力。

TCP窗口是如何工作的

client和server端建立連接後,client會告訴server,自己的"接收窗口"大小(自己能接收多少的數據,受上面所說的 buffer影響),server端接收到client的"接收窗口"大小,就會變成server端自己的"發送窗口"大小。同樣的,server端告訴 client自己的"接收窗口"大小,就會變成客戶端的"發送窗口"大小。

為了理解TCP的窗口大小是怎麼樣變化的,我們先需要理解它的含義。最簡單的方式就是認為窗口大小"意味著接收方能接收數據的大小",這也是說接收 端設備再應用程序讀取buffer中數據之前,能從對端連接處理多少數據。比如說server端窗口大小是360,那麼就意味著server端一次只能從 客戶端接收不超過360bytes的數據。當server端收到數據,它會將數據放到buffer裡,然後server端必須對這份數據做兩件事

1. server端必須發送一個 ACK 到client端來確認數據已經收到
2. server端必須處理這份數據,把它交給對應的應用程序

要區分上面兩件事對理解窗口很重要,接收方收到數據後會確認,但是數據並不一定是裡面就是從buffer裡取出的,這是受應用層邏輯控制的。所以很 有可能如果接收數據過快,而取出數據更慢,就會導致buffer滿。一旦這種情況發生,窗口大小就開始調整來防止接收方負載過高。

正是因為窗口大小的調整可以用來調節數據傳輸的速率,所以就可以實現TCP的流控,在傳輸層的流控就是典型的例子,流控對於TCP的通信是很重要的,通過增大或者減小窗口的大小,client和server各自確保彼此設備發數據和收數據平衡。

通過TCP窗口實現流控

下面舉一個例子,來看TCP窗口大小變化怎樣實現流控。client端和server端已經三次握手建立TCP連接,總窗口大小是TCP建立連接時 候確定的。黑色框代表client和server總的窗口大小,紅色框代表實際可用的窗口大小。初始化的時候默認client和server總窗口和可用 端口分別都是360。另外,假設Client總共只發送360bytes數據,所以總窗口大小不會往前移動。

  1. client 發送140bytes到server端,Seq=1,Length=140;可用窗口大小往前移動,變成260bytes,總窗口大小不變,依然是360。這中間的120是已發送,等待確認;
  2. server端收到140bytes,放入buffer中,但是應用程序很繁忙,只取出100個字節。這時候可用窗口大小: 260(360-100)。接著server端要給client發確認,Ack=141,Window=260。黑框左邊緣向前移動,表示140字節已經 確認收到,但是應用程序太慢,處理很忙導致我現在只能處理260bytes(回顧下上面server端收到數據要做的兩件事);
  3. client收到來自server端的ack回應,首先總窗口左邊緣向前移動,表示第一步的140bytes server已經收到,剩下260數據。接著被告知server的可接收窗口是260,client就調整自己的發送窗口是260,表示一次發數據不能超 過260;
  4. client發送180bytes,可用窗口變成80(260-180),等待確認發送的180bytes;
  5. server收到180bytes,放入buffer中,應用程序依然很繁忙,這次一個字節都不處理。此時可用窗口大小:80(260-180),然後發180 ack給client,並告知窗口大小80;
  6. client收到ack,確認之前發送的180已經到達,剩余數據還有80字節。被告知server端接收窗口大小是80,調整自己的發送窗口大小為80
  7. client發送80bytes,可用窗口變成0(80-80),等待確認發送的80bytes;
  8. server收到180bytes,放入buffer中,應用程序依然很繁忙,一個字節都不處理。此時可用窗口大小:80(80-80),然後發80 ack給client,並告知窗口大小0;
  9. client收到ack,確認之前發送的80已經到達。被告知server端接收窗口大小是0,調整自己的發送窗口大小為0,此時無論client是否還有數據要發送,都不能再發了。

總結

窗口就是量化接收端和服務端當前能處理數據的能力。個人理解,如發現接收端的窗口越來越小,或者越來越大,都可能會有問題。

1. 接收端的窗口越來越小,那麼就是接收端處理不過來(1.發的程序太快,太多;2.收的程序太慢,太少;3.發端帶寬比收端帶寬更大),會導致接收端發送給發送端的窗口變小,從而發送端調整發送窗口大小,降低發送速度,網絡流量就會下降。
2. 接收端的窗口越來越大,那麼就是發送端處理不過來(1.收的程序太快,太多;2.發的程序太慢,太少;3.發端帶寬比收端帶寬更小),會導致接收端發送給發送端的窗口變大,從而發送端調整發送窗口大小,增加發送速度,網絡流量就會升高。
Copyright © Linux教程網 All Rights Reserved