TCP流量控制-滑動窗口協議&Nagle算法

一.滑動窗口

服TCP全雙工; A給B發送數據,則A有發送緩衝區; B有接收緩衝區。應用層的所有需要發送的數據都被放在了發送者的發送緩衝區。發送窗口是發送緩存中的一部分, 是可以被TCP協議發送的那部分。

發送緩衝區:

已發送並收到確認的數據、已發送但未收到確認的數據允許發送但尚未發送的數據,以及暫不允許發送的數據;

黃色部分組成了發送窗口(p1到p3)

 每次成功發送數據之後,發送窗口就會在發送緩衝區中按順序移動(前提:前面的數據包收到確認之後),將新的數據包含到窗口中準備發送

二.流量控制

建立連接的時候,B會告訴A,自己的接收窗口大小(rwnd)。B每次給A回覆確認數據包(ACK) ,也會告訴A自己的接收窗口大小。如果B告訴A自己的緩衝區己滿(rwnd=0), A則停止發送數據。

(這裏引入一個問題:A是知道什麼時候在發送數據的呢,如果B接手窗口開放了,A也不會一直停止,總該在此發送呀)

這裏就和上篇我們講到的堅持定時器(持續定時器)相關了。大家可以回顧一下

就是通過這個16位的窗口大小告訴發送端接收端的窗口大小的

 

三.傳輸效率

單個發送字節單個確認,小包造成網絡擁塞:

如果一個小包就要封裝成報文段,加上TCP IP,和數據鏈路的報頭。這樣一個報文利用率就很低,再者同樣大小的數據

分成若干個小報文段分成若干個大報文段,明顯前者會浪費大量的網絡資源。

針對上面的問題引出了Nagle算法

Nagle算法:儘可能次多 發送幾個字節,避免網絡因爲太多的小包(協議頭的比例非常之大)而擁塞。只允許個未被ACK的包存 在於網絡(後面這個話的意思就是發送端發送一個數據包給接收端,在沒有收到接收端的ACK之前,是不會發送下一個數據包的)

1.如果包長度達到MSS,則允許發送:

2.如果該包含有FIN,則允許發送(如果是終止報文段就直接發)

3.設置了TCP NODELAY選項, 則允許發送:禁止Nagile算法。(就不用延遲打包了)

4.Copk算法是Nagle算法的增強版,就是收到接收端確認後可以不用馬上發送數據

未設置TCP CORK選項時,若所有發出去的小數據包(包長度小於MSS)均被確認,則允許發送設置該選項後,內核會盡力把小數據包拼接成個大的數據包 (-個MTU) 再發送出去,當然若定時間後-般爲200ms,該值尚待確認),內核仍然沒有組合成一個MTU時 也必鬚髮送現有的數據,CORK算法的目的是提高網絡的利用率,使得總體上協議頭佔用的比例儘可能的小

int on = 1;

setsockopt(sockfd, SOL_TCP, TCP_COPK, &on, sizeof(on));

5.上述條件都未滿足,但發生了超時(-一般爲200ms)。則立即發送接收方等待段時間, 或者接收方獲得足夠的空間容納一個報文段或者等到接收緩存有 半空閒的時候, 再通知發送方發送數據

 

更多的C/C++ linux編程我會在下面的文章中陸續的分享,也可以關注‘奇牛學院’

來一起討論

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章