相較于UDP,TCP有以下區別:
1、可靠傳輸
2、流量控制
這兩個功能都是依靠滑動視窗來實作的,本文就來解密TCP中的滑動視窗,
TCP實作可靠傳輸依靠的有 序列號、超時重傳、滑動視窗、確認應答等機制,
序列號
首先我們說下序列號,TCP中將要發送的資料包的每個位元組都分配了序列號,用來唯一標識一個位元組,序列號隨著資料包的發送而增加,
只有為每個位元組分配一個序列號,每個資料包都對應著一個序列號區間,才能確定哪個資料包發送出現意外了,
序列號的初始化是由作業系統分配的,是一個32位的數字,
TCP初始化序列號不能設定為一個固定值,因為這樣容易被攻擊者猜出后續序列號,從而遭到攻擊,
RFC1948中提出了一個較好的初始化序列號ISN隨機生成演算法,
ISN = M + F(localhost, localport, remotehost, remoteport).
M是一個計時器,這個計時器每隔4us加1,
F是一個隨機演算法,根據源IP、目的IP、源埠、目的埠生成一個亂數值,
確認應答
當接收方收到一個資料包后,會直接回傳一個ACK包,或者延遲一段時間回傳一個ACK包,一次性確認多個資料包,
ACK包中有一個ack欄位,代表著seq小于ack的資料包都已經被接收完畢,

超時重傳
當TCP發送端發送了一個TCP資料包的時候,會設定一個定時器,如果在定時器期間沒有收到接收方對這個資料包的確認應答包,也成為ACK包,就會重新發送對應的TCP資料包,
超時重傳有以下兩個原因:
1、資料包丟失
2、ack資料包丟失

超時時間的選擇
超時時間既不能太長,又不能太短,
超時時間過長存在的問題:
當發生丟包的時候,需要等待好長時間才會重新發送,這個時候TCP就處于等待時期,什么也干不了,浪費資源,發送效率低下,
超時時間過短存在的問題:
如果超時時間太短,會發生多次發送重復包的情況,當ACK包還在路上的時候,由于超時時間太短而導致發送端重復的發送不必要的資料包,會加重網路的負擔,導致網路阻塞等問題,網路發生阻塞的話,會進一步正反饋導致更多的重傳,
重傳超時時間簡稱為RTO
RTO是略大于RTT的,
RTT指的是一個資料包從發送到接收到ACK確認包的花費時間,RTT是會隨著網路的變化而變化,是會波動的,
滑動視窗的出現原因
滑動視窗 分為 發送視窗 和 接收視窗,
發送視窗 用來 發送資料,
接收視窗 用來 接收資料,
客戶端和服務器端 都有一個 發送視窗 和 接收視窗,
為什么會引入滑動視窗呢?
如果不存在發送視窗的話,TCP發送一個資料包后會等待ACK包,因為必須要保存對應的資料包,資料包很有可能需要重新發送,
這樣的話發送效率會很慢,大部分時間都在等待,

引入了發送視窗,發送視窗的做法是:
只要處于視窗范圍中的位元組都可以被發送,不需要等待前面位元組的ack包,
發送視窗的本質就是在作業系統中開辟的一塊緩沖區,用來存放當前需要發送的資料,當接收到ack的時候,會將seq小于ack的資料從緩沖區中移除,可以發送新的資料,
如果發送視窗的大小為3個TCP資料包,那么發送方就可以連續發送3個TCP資料包,而不用等待前2個資料包的ack包,

滑動視窗詳解
發送視窗

發送視窗分為四個部分:
1、已經發送并且已經收到ack包的資料
2、已經發送還未接收到ack包的資料
3、允許發送但是還未發送的資料
4、不允許發送的資料
TCP中用三個指標來區分這個四個部分

指標1: 指向第一個已發送但是未接收到ack的位元組
指標2: 指向第一個允許發送但是還未發送的位元組
指標3: 發送視窗的大小
這時還允許發送資料,就會將可用視窗中的資料發送給接收視窗,

這個時候,可用視窗大小為0,這個時候會等待接收方發送ack包,
如果這個時候如果接收一個ack包為37,這個時候發送視窗會向右邊移動5位,52-56會變成可用視窗,

接收視窗
接收視窗中的位元組序列號都是與發送視窗一一對應的,

接收視窗分為三部分:
1、已經接收的資料
已經接收到的資料,
2、接收視窗中的資料
接收視窗中資料是可以接收資料,但是還未收到資料的區域
3、還未收到的資料
還不能接收資料的區域
接收視窗由一個RCV_NEXT和接收視窗大小window來維護,
接收視窗有以下情況:
1、當資料包的seq == RCV_NEXT的資料包的時候,將接收視窗的RCV_NEXT右移到第一個空的槽位中;
2、當資料包的seq > RCV_NEXT 并且seq < RCV_NEXT+ window的時候,會將其加入到滑動視窗中對應的位置,
3、如果資料包的seq < RCV_NEXT,說明該資料包已經被接收了,但是對應的ack包因為阻塞或者例外沒有發送到發送方,
這時接收方會利用其發送視窗發送一個ack包,
滑動視窗的大小
發送視窗的大小要取決于接收視窗,如果發送視窗大于接收視窗的大小,會導致接收視窗無法完全接收資料包,導致一些資料包被丟棄,導致發送視窗的超時重傳,浪費資源,
tcp報文頭部中有一個window欄位,代表著接收視窗的接收資料能力,發送視窗會根據window欄位來調整發送視窗大小,保證接收視窗正常接收資料包,
發送視窗的大小不能超過接收視窗的大小,否則接收視窗不能正常接收資料,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/299501.html
標籤:其他
上一篇:Websocket入門
