# 網絡基本功(十一):TCP窗口調整與流控
**轉載請在文首保留原文出處:EMC中文支持論壇**[https://community.emc.com/go/chinese](https://community.emc.com/go/chinese) [](http://service.weibo.com/share/share.php?title=%23ECN%e4%b8%ad%e6%96%87%e6%94%af%e6%8c%81%e8%ae%ba%e5%9d%9b%23 %e7%bd%91%e7%bb%9c%e5%9f%ba%e6%9c%ac%e5%8a%9f%ef%bc%88%e5%8d%81%e4%b8%80%ef%bc%89%ef%bc%9aTCP%e7%aa%97%e5%8f%a3%e8%b0%83%e6%95%b4%e4%b8%8e%e6%b5%81%e6%8e%a7 @EMC%e6%98%93%e5%ae%89%e4%bf%a1%e4%b8%ad%e5%9b%bd%e6%8a%80%e6%9c%af%e7%a4%be%e5%8c%ba&url=https://community.emc.com/message/843667#843667)
## 介紹
前文已經介紹過了TCP滑動窗口大小的重要性。在客戶端與服務器的連接中,客戶端告知服務器它一次希望從服務器接收多少字節數據,這是客戶端的接收窗口,即服務器的發送窗口。類似地,服務器告知客戶端一次希望從客戶端接收多少字節數據,也就是服務器的接收窗口和客戶端的發送窗口。
要理解為什么窗口大小會產生波動,首先需要理解它的含義。最簡單的方式是它代表了設備對于特定連接的接收緩存大小。即,窗口大小代表一個設備一次能夠從對端處理多少數據,之后再傳遞給應用層處理。
## 更多信息
當服務器從客戶端接收數據,它就將數據放在緩存中,服務器必須對數據做以下兩步操作:
**確認**:服務器必須將確認信息發回客戶端以表明數據接收。
**傳輸**:服務器必須處理數據,將它傳遞給目標應用程序處理。
區分開這兩件事情是非常重要的。關鍵在于基本的滑動窗口機制中,數據于接收時確認,但并不一定立即從緩存中傳輸出去。也就意味著當接收數據速度快于接收TCP處理速度時,緩存有可能被填滿。當這一情況發生時,接收設備需要調整窗口大小已防止緩存過載。
由于窗口大小能夠以這種方式管理連接兩端設備數據流的速率,TCP就是以這種方式實現流控這一傳輸層非常典型的任務。流控對于TCP來說是很重要的,因為它是設備間互通狀態的方式。通過增加或縮小窗口大小,服務器和客戶端能夠確保對端發送數據的速度等同于處理速度。
**減小窗口大小以降低發送速率:**
首先看一下客戶端到服務器的數據傳輸,如下圖所示。
[](https://community.emc.com/servlet/JiveServlet/showImage/2-843667-97608/image002.jpg)
客戶端傳輸140字節數據至服務器。之后,客戶端的可用窗口還剩下220字節:發送窗口的360字節減去發送的140字節。
一段時間過后,服務器接收到140字節并將它們放在緩存中。現在,理想的情況下,140字節進入緩存,確認之后立刻從緩存移出。也就是說,緩存有足夠的大小來容納客戶端發送的所有數據。緩存的空閑空間維持在360字節,因此告知客戶端窗口大小保持不變。
只要服務器處理速度和數據進入速度相同,窗口大小就會保持在360字節。客戶端在接收到140字節的確認信息以及窗口大小保持不變的信息之后,將360字節窗口向右移動140字節。由于現在未確認字節數為0,因此客戶端又可以發送360字節數據。對應于之前可用窗口的220字節,加上剛剛確認的140字節數據。
然而,現實中服務器可能需要處理數十,數百乃至數千個TCP連接。TCP可能無法立刻處理數據,或應用應用程序本身無法接收140字節數據。任何一種情況下,服務器TCP都無法立刻將140字節從緩存中移出。這時,除了發回確認信息給客戶端以外,服務器會想要告知客戶端更改窗口大小,以表示緩存已經被部分寫入了。
假設我們接收到140字節,但只能發送40字節給應用程序,緩存中剩下100字節。當發送140字節的確認信息,服務器將發送窗口縮小100字節,至260字節。當客戶端從服務器接收到這一片段,它將會看到140字節的確認信息并將窗口向右滑動140字節。在滑動過程中,將大小縮減至260字節。可以認為將窗口左端滑動140字節,但右端僅滑動40字節。新的稍小一些的窗口保證服務器從客戶端接收最多260字節數據,以適應接收緩存中的剩余空間,如下圖的1-3步所示。
[](https://community.emc.com/servlet/JiveServlet/showImage/2-843667-97609/image003.jpg)
**縮減發送窗口以停止發送新數據:**
如果服務器無法接收任何新數據會怎么樣呢?假設客戶端下一次傳輸180字節,但是服務器太忙碌而無法對其進行處理。這種情況下,服務器將這180字節緩存下來,并且在確認信息中,將窗口大小從260字節縮減為80字節。當客戶端接收到180字節的確認信息,它也會看到窗口縮減了180字節,它會滑動與縮減同樣的大小,告知服務器:我確認接收180字節數據,但不允許你再發送新的數據。也可以看作窗口左端滑動180字節,但右端維持不動。只要右端不移動,客戶端就無法發送更多數據。這一過程顯示在上圖的4-6中。
**關閉發送窗口:**
窗口調整可以通過雙方設備來完成。如果服務器從客戶端接收的數據持續快于推送給應用的速率,則服務器將會繼續減小接收窗口。假設發送窗口減小至80字節,客戶端發送第三個請求,長度為80字節,但服務器仍處于繁忙狀態。之后服務器將窗口減小為0,也稱為關閉窗口。這一信息告知客戶端服務器已經過載,它需要徹底停止發送數據,如上圖最后一步所示。之后,當服務器負載減輕時,可以再次增加這一連接的窗口,允許更多數據傳輸。
- 介紹
- 網絡基本功(一):細說網絡傳輸
- 網絡基本功(二):細說交換機
- 網絡基本功(三):細說VLAN與Trunk
- 網絡基本功(四):細說路由(上)
- 網絡基本功(五):細說路由(下)
- 網絡基本功(六):鏈路聚合
- 網絡基本功(七):細說IP地址與子網
- 網絡基本功(八):細說TCP滑動窗口
- 網絡基本功(九):細說TCP重傳
- 網絡基本功(十):細說TCP確認機制
- 網絡基本功(十一):TCP窗口調整與流控
- 網絡基本功(十二):細說Linux網絡配置(上)
- 網絡基本功(十三):細說Linux網絡配置(下)
- 網絡基本功(十四):細說診斷工具ping
- 網絡基本功(十五):細說網絡性能監測與實例(上)
- 網絡基本功(十六):細說網絡性能監測與實例(下)
- 網絡基本功(十七):細說tcpdump的妙用(上)
- 網絡基本功(十八):細說tcpdump的妙用(下)
- 網絡基本功(十九):細說NAT原理與配置
- 網絡基本功(二十):細說ICMP和ARP
- 網絡基本功(二十一):細說HTTP(上)
- 網絡基本功(二十二):細說HTTP(下)
- 網絡基本功(二十三):Wireshark抓包實例診斷TCP連接問題
- 網絡基本功(二十四):Wireshark抓包實例分析TCP重傳
- 網絡基本功(二十五):Wireshark抓包實例分析TCP重復ACK與亂序
- 網絡基本功(二十六):Wireshark抓包實例分析TCP窗口及reset
- 網絡基本功(二十七):Wireshark抓包實例分析HTTP問題(上)
- 網絡基本功(二十八):Wireshark抓包實例分析HTTP問題(下)
- 網絡基本功(二十九):Wireshark抓包實例診斷數據庫常見問題
- 網絡基本功(三十):細說DNS(上)
- 網絡基本功(三十一):細說DHCP