天天看點

(五)深入淺出TCPIP之TCP流量控制

TCP流量控制

   我們都知道TCP是一種可靠的,面向連接配接的傳輸層協定。我們總是希望TCP能夠傳輸的資料越快越好。如果存在這樣一種情況,發送方資料發送的非常快,而且接收方耗盡自己的資源也根本來不及接收,那這些多餘的資料就會被丢棄,這就違背了TCP可靠的宗旨了。

   是以就需要引入一種流量控制的手段:讓發送方不要發送太快,既讓接收方能夠順利接收資料,而且也不會造成網絡鍊路的阻塞。 

滑動視窗

為了讓發送方不要發送的太快。那就讓接收方控制發送方的資料大小,每次應答的時候通知發送方自己還剩多少空間可以接收資料。那麼滑動視窗類似一個視窗,是用來告訴發送方可以發送資料的大小。也可以說是視窗标記了接收方緩沖區的大小。視窗大小也就表示一次能發送多少資料量,而且這個視窗可以滑動,滑動視窗是以得名。

固定視窗和滑動視窗

我們可以看下面一張圖來分析一下固定大小視窗有什麼問題。

   這裡我們可以看到假設視窗大小是1,也是就每次隻能發送一個資料隻有接收方對這個資料進行确認了以後才能發送第2個資料。我們可以看到發送每發送一個資料接收方就要給發送方一個ACK對這個資料進行确認。隻有接收到了這個确認資料以後發送方才能傳輸下個資料。這樣我們考慮一下如果說視窗過小,那麼當傳輸比較大的資料的時候需要不停的對資料進行确認,這個時候就會造成很大的延遲。如果說視窗大小定義的過大。我們假設發送方一次發送100個資料,但接收方隻能處理50個資料。這樣每次都會隻對這50個資料進行确認。發送方下一次還是發送100個資料,但是接收方還是隻能處理50個資料。這樣就避免不了不必要的資料來擁塞我們的鍊路。是以我們就引入了滑動視窗機制,視窗大小并不是固定的而是根據我們之間的鍊路的帶寬的大小,這個時候鍊路是否擁塞,接收方是否能處理這麼多資料了。

我們看看滑動視窗是如何工作的,我們看下面幾張圖

首先是第一次發送資料,這個時候的視窗的大小是根據鍊路帶寬的大小決定的。我們假設這個時候視窗大小是3,這個時候接收方收到資料以後會對資料進行确認告訴發送方我下次希望收到的資料是多少。這裡我們看到接收方發送的ACK = 3(這是發送方發送序列2的回答确認,下一次接收方期望接收的是3序列信号)。這個時候發送方收到這個資料以後就知道第一次發送的3個資料對方隻接收了2個。就知道第3個資料對方沒有收到。下次在發送的時候就從第3個資料開始發,這時候視窗大小就變成了2

這個時候發送方發送2個資料

看到接收方發送的ACK是5就表示它下一次希望收到的資料是5,發送方就知道我剛才發送的2個資料對方接收了,這個時候開始發送第5個資料。

這就是滑動視窗的工作機制,當鍊路變好了或者變差了,這個視窗還會發生變化,并不是第一次協商好了以後就永遠不變了。

如何告知發送方視窗大小

如何通知發送方視窗大小呢?難道要重新發送一包資料告訴對方嗎,這顯然是不合理的。可以巧妙的使用确認應答包。需要在三次握手時候,就告知對方。在原來的确認應答政策中,每一次發送資料,都需要Ack應答,在接收到Ack之後才會發送下一個資料段,發送方沒有接收到Ack應答呢?這樣做的方式效率實在太低。使用了滑動視窗,可以多次發送資料,隻要不要超過對方視窗大小。這樣就大大提高了效率。

滑動視窗細節

  1. 接收方将自己能夠接收的緩沖區大小是在TCP首部中的“視窗大小”字段表示的,通過Ack通知發送方。
  2. 視窗大小是發送方可以發送資料的,也就是說可以不需要Ack應答,可以發送多次資料,前提發送總資料量不要超過視窗大小。
  3. 視窗大小大說明網絡的吞吐率高
  4. 作業系統核心維護了一塊接收緩沖區,隻有Ack應答之後的資料才能從緩沖區中删除。
  5. 接收方一旦發現自己的緩沖區快滿了,就會通知對方自己的視窗為更小的值。
  6. 如果接收方發現自己的緩沖區滿了,就會将視窗的大小設定為0,此時發送方将不再發送資料,但是需要定期發送一個視窗探測資料段,使接收方把視窗大小告訴發送方 。(針對這一點重點說明下為什麼需要定期發送視窗探針?可以想象下,如果接收方緩沖區滿了,然後通過Ack告知發送方視窗大小為0。發送方從此不會發送資料給接收方,接收方也沒辦法告知對方自己緩沖區可以接收資料,就會出現“卡死”的情況)                    

流量控制是端到端的控制,例如A通過網絡給B發資料,A發送的太快導緻B沒法接收(B緩沖視窗過小或者處理過慢),這時候的控制就是流量控制,原理是通過滑動視窗的大小改變來實作。

執行個體

A 向 B 發送資料。在連接配接建立時,B 告訴 A:“我的接收視窗 rwnd = 400(位元組)。注意:圖中的箭頭上面大寫的ACK表示首部中的确認位ACK,小寫ack表示确認字段的值。

上面的過程是這樣的:

  1. A發送了資料序号1至100,還能發送300位元組
  2. A發送了資料序号101至200,還能發送200位元組
  3. A發送了資料序号201至300,但是丢失了資料
  4. B發送了ACK,同時通知A,允許A發送序号201至500,300位元組
  5. A發送了資料序号301至400,還能發送100位元組
  6. A發送了資料序号401至500,不能發送資料了
  7. A逾時重傳舊的資料,但不能發送新資料
  8. B發送了ACK,同時通知A,允許A發送序号501至600,100位元組
  9. A發送了資料序号501至600,不能發送資料了
  10. B發送了ACK,同時通知A,不允許A發送資料

注意流量控制和擁塞控制的差別:

流量控制是指點對點通信的控制,做的是抑制發送端發送資料的速率,便于接收端來得及接收。

擁塞控制是防止過多的資料注入網絡中,使得網絡中路由器或鍊路不緻過載,有一個前提是,網絡能夠承受現有的網絡負荷,是一個全局性過程;

連環發問

1、TCP有幾個滑動視窗?

 這裡說明下,由于TCP/IP支援全雙工傳輸,是以通信的雙方都擁有兩個滑動視窗,一個用于接受資料,稱之為接收視窗;一個用于發送資料,稱之為擁塞視窗(即發送視窗)。指出接受視窗大小的通知我們稱之為視窗通告。

2、接收視窗的大小固定嗎?

在早期的TCP協定中,接受接受視窗的大小确實是固定的,不過随着網絡的快速發展,固定大小的視窗太不靈活了,成為TCP性能瓶頸之一,也就是說,在現在的TCP協定中,接受視窗的大小是根據某種算法動态調整的。

3、接受視窗越大越好嗎?

接受視窗如果太小的話,顯然這是不行的,這會嚴重浪費鍊路使用率,增加丢包率。那是否越大越好呢?答否,當接收視窗達到某個值的時候,再增大的話也不怎麼會減少丢包率的了,而且還會更加消耗記憶體。是以接收視窗的大小必須根據網絡環境以及發送發的的擁塞視窗來動态調整。