TCP滑动窗口(发送窗口和接受窗口)
TCP窗口機(jī)制
TCP header中有一個(gè)Window Size字段,它其實(shí)是指接收端的窗口,即接收窗口。用來(lái)告知發(fā)送端自己所能接收的數(shù)據(jù)量,從而達(dá)到一部分流控的目的。
其實(shí)TCP在整個(gè)發(fā)送過(guò)程中,也在度量當(dāng)前的網(wǎng)絡(luò)狀態(tài),目的是為了維持一個(gè)健康穩(wěn)定的發(fā)送過(guò)程,比如擁塞控制。因此,數(shù)據(jù)是在某些機(jī)制的控制下進(jìn)行傳輸?shù)模褪谴翱跈C(jī)制。
窗口縮放因子(Window Scaling)
以前,window size最大為2的16次方,為65535,隨著寬帶不斷提高,65535字節(jié)已經(jīng)小了,為了突破限制,便有了Window Size Scaling選項(xiàng),假設(shè)window scale為7,也就是要將Window Size的值左移七位,即乘以128。window scale最大為14.
在整個(gè)雙方的交互過(guò)程中,發(fā)送方和接收方Window size scaling factor乘積因子必須保持不變,但是發(fā)送方的乘積因子和接收方的乘積因子可以不同,由各自決定。
在標(biāo)志位中有SYN的消息,會(huì)在選項(xiàng)中通知接收方,本端具體的放大因子,該消息本身不放大
上圖中的放大因子擴(kuò)大了256倍,8212*256=2102272
發(fā)送窗口
(1)已經(jīng)發(fā)送并且對(duì)端確認(rèn)(Sent/ACKed)---------------發(fā)送窗外 緩沖區(qū)外
(2)已經(jīng)發(fā)送但未收到確認(rèn)數(shù)據(jù)(Sent/UnACKed)----- --發(fā)送窗內(nèi) 緩沖區(qū)內(nèi)
(3)允許發(fā)送但尚未防的數(shù)據(jù)(Unsent/Inside)-----------發(fā)送窗內(nèi) 緩沖區(qū)內(nèi)
(4)未發(fā)送暫不允許(Unsent/Outside)-------------------發(fā)送窗外 緩沖區(qū)內(nèi)
2,3兩部分為發(fā)送窗口
接受窗口
對(duì)于TCP的接收方,在某一時(shí)刻在它的接收緩存內(nèi)存在3種。“已接收”,“未接收準(zhǔn)備接收”,“未接收并未準(zhǔn)備接收”(由于ACK直接由TCP協(xié)議棧回復(fù),默認(rèn)無(wú)應(yīng)用延遲,不存在“已接收未回復(fù)ACK”)。其中“未接收準(zhǔn)備接收”稱之為接收窗口。
發(fā)送窗口與接收窗口關(guān)系
TCP是雙工的協(xié)議,會(huì)話的雙方都可以同時(shí)接收、發(fā)送數(shù)據(jù)。TCP會(huì)話的雙方都各自維護(hù)一個(gè)“發(fā)送窗口”和一個(gè)“接收窗口”。其中各自的“接收窗口”大小取決于應(yīng)用、系統(tǒng)、硬件的限制(TCP傳輸速率不能大于應(yīng)用的數(shù)據(jù)處理速率)。各自的“發(fā)送窗口”則要求取決于對(duì)端通告的“接收窗口”,要求相同。
滑動(dòng)窗口
TCP并不是每一個(gè)報(bào)文段都會(huì)回復(fù)ACK的,可能會(huì)對(duì)兩個(gè)報(bào)文段發(fā)送一個(gè)ACK,也可能會(huì)對(duì)多個(gè)報(bào)文段發(fā)送1個(gè)ACK【累計(jì)ACK】,比如說(shuō)發(fā)送方有1/2/3 3個(gè)報(bào)文段,先發(fā)送了2,3 兩個(gè)報(bào)文段,但是接收方期望收到1報(bào)文段,這個(gè)時(shí)候2,3報(bào)文段就只能放在緩存中等待報(bào)文1的空洞被填上,如果報(bào)文1,一直不來(lái),報(bào)文2/3也將被丟棄,如果報(bào)文1來(lái)了,那么會(huì)發(fā)送一個(gè)ACK對(duì)這3個(gè)報(bào)文進(jìn)行一次確認(rèn)。
滑動(dòng)窗口實(shí)現(xiàn)面向流的可靠性
最基本的傳輸可靠性來(lái)源于“確認(rèn)重傳”機(jī)制。
TCP的滑動(dòng)窗口的可靠性也是建立在“確認(rèn)重傳”基礎(chǔ)上的。
發(fā)送窗口只有收到對(duì)端對(duì)于本段發(fā)送窗口內(nèi)字節(jié)的ACK確認(rèn),才會(huì)移動(dòng)發(fā)送窗口的左邊界。
接收窗口只有在前面所有的段都確認(rèn)的情況下才會(huì)移動(dòng)左邊界。當(dāng)在前面還有字節(jié)未接收但收到后面字節(jié)的情況下,窗口不會(huì)移動(dòng),并不對(duì)后續(xù)字節(jié)確認(rèn)。以此確保對(duì)端會(huì)對(duì)這些數(shù)據(jù)重傳。
滑動(dòng)窗口的流控特性
TCP的滑動(dòng)窗口是動(dòng)態(tài)的,我們可以想象成小學(xué)常見(jiàn)的一個(gè)數(shù)學(xué)題,一個(gè)水池,體積V,每小時(shí)進(jìn)水量V1,出水量V2。當(dāng)水池滿了就不允許再注入了,如果有個(gè)液壓系統(tǒng)控制水池大小,那么就可以控制水的注入速率和量。這樣的水池就類似TCP的窗口。應(yīng)用根據(jù)自身的處理能力變化,通過(guò)本端TCP接收窗口大小控制來(lái)對(duì)對(duì)對(duì)端的發(fā)送窗口流量限制。
應(yīng)用程序在需要(如內(nèi)存不足)時(shí),通過(guò)API通知TCP協(xié)議棧縮小TCP的接收窗口。然后TCP協(xié)議棧在下個(gè)段發(fā)送時(shí)包含新的窗口大小通知給對(duì)端,對(duì)端按通知的窗口來(lái)改變發(fā)送窗口,以此達(dá)到減緩發(fā)送速率的目的。
滑動(dòng)窗口動(dòng)態(tài)調(diào)整
主要是根據(jù)接收端的接收情況,動(dòng)態(tài)去調(diào)整Window Size,然后來(lái)控制發(fā)送端的數(shù)據(jù)流量
客戶端不斷快速發(fā)送數(shù)據(jù),服務(wù)器接收相對(duì)較慢,看下實(shí)驗(yàn)的結(jié)果
a. 包175,發(fā)送ACK攜帶WIN = 384,告知客戶端,現(xiàn)在只能接收384個(gè)字節(jié)
b. 包176,客戶端果真只發(fā)送了384個(gè)字節(jié),Wireshark也比較智能,也宣告TCP Window Full
c. 包177,服務(wù)器回復(fù)一個(gè)ACK,并通告窗口為0,說(shuō)明接收方已經(jīng)收到所有數(shù)據(jù),并保存到緩沖區(qū),但是這個(gè)時(shí)候應(yīng)用程序并沒(méi)有接收這些數(shù)據(jù),導(dǎo)致緩沖區(qū)沒(méi)有更多的空間,故通告窗口為0, 這也就是所謂的零窗口,零窗口期間,發(fā)送方停止發(fā)送數(shù)據(jù)
d. 客戶端察覺(jué)到窗口為0,則不再發(fā)送數(shù)據(jù)給接收方
e. 包178,接收方發(fā)送一個(gè)窗口通告,告知發(fā)送方已經(jīng)有接收數(shù)據(jù)的能力了,可以發(fā)送數(shù)據(jù)包了
f. 包179,收到窗口通告之后,就發(fā)送緩沖區(qū)內(nèi)的數(shù)據(jù)了.
總結(jié)一點(diǎn),就是接收端可以根據(jù)自己的狀況通告窗口大小,從而控制發(fā)送端的接收,進(jìn)行流量控制
參考:
TCP 滑動(dòng)窗口(發(fā)送窗口和接收窗口)
解析TCP之滑動(dòng)窗口(動(dòng)畫(huà)演示)
TCP-IP詳解:滑動(dòng)窗口(Sliding Window)
總結(jié)
以上是生活随笔為你收集整理的TCP滑动窗口(发送窗口和接受窗口)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Apache】Apache服务的安装(
- 下一篇: 巨鹿之战是哪两支军队之间的战斗?