您好,登錄后才能下訂單哦!
該撣撣這里的灰塵了,寫一篇關于TCP的文章吧。今天的主題是TCP的滑動窗口。在開始這個話題之前,我想先提幾個關于TCP協議的常見誤區。
誤區1:TCP協議三次握手過程中后兩個包都是[ACK]包。
解釋:這種說法并不錯,只是不嚴謹。首先,第一個包是[SYN],SYN位在TCP報頭flag字段中,見上圖TCP報頭結構。第二個包更確切地說應該叫[SYN,ACK]包,因為除了ACK位被置位以外,SYN位也被置位了。第三個包才是單純的ACK包,因為只有ACK位被置位。所以三次握手的過程為:
客戶端----[SYN]------------------>>>服務器
客戶端<<<-------------[SYN,ACK]---服務器
客戶端----[ACK]------------------>>>服務器
有一種非常經典的***叫SYN Flood***,是DDOS***的一種,方法是客戶端發送多個SYN包請求但是不回復第三個ACK包以占用服務器有限的資源。
誤區2:TCP數據傳輸過程中,序列號增長的單元是包的個數。
解釋:這是初學者最常犯的一個錯誤,原因是絕大多數老師為了方便學生理解,剛開始舉例子時序列號都是+1地往上增。其實不然。序列號增長的單元是包應用層數據(也叫Payload)的字節數。
舉個栗子:
假如某一個數據包序列號:1000,Payload長度500。那么下一個包的序列號就是1500。
誤區3:對于TCP連接的雙方,序列號都會增長。
解釋:對于多數應用(HTTP,Telnet),雙方都存在數據的發送,那么雙方的序列號都會增長,而對于FTP這樣的應用,在數據通道中,只是某一方在傳輸數據(上傳或下載),那么另一方只是在扮演簡單確認的角色,在這種情況下,另一方的序列號并不會增長。
說了這么多,現在開始進入正題,來聊聊TCP的窗口機制,這是理解TCP協議的一個關鍵點。
1. 大家都知道TCP和UDP的區別是,TCP是基于連接的(三次握手),而且TCP數據的傳輸是可靠的,所謂可靠是依托序列號及確認號機制讓TCP的傳輸過程中即使出現丟包也會重傳。
2. 但是TCP的確認機制也讓TCP連接雙方的數據傳輸速度變慢,也就是說,一方發送數據需要等待對方的確認才繼續發送后續數據。這就體現的窗口機制的作用,所謂窗口,也就是充分利用雙方的帶寬及緩沖區(Buffer)。舉個栗子,發送方不必等待對方的確認,可以連續發送多個數據包給對方,而對方可以暫時把這些數據存放在緩沖區,并給對方一個確認。這樣,可以大大增加數據傳輸的速度。
3. 這樣做的問題是一旦當接收方的緩沖區填滿或即將填滿時,就會產生不堪重負的情況,那么這就需要TCP窗口的實時更新機制,舉個栗子,接收方窗口大小設置的是50000,也就是說發送方可以不必等待確認而一次性發送50000字節的數據,一旦接收方意識到不堪重負的情況,可以發送窗口更新通知告訴發送方,現在的窗口大小是30000,請減少一次性發送數據的字節數。某些極端情況,接收方的Buffer完全填滿,這時,會發送ZeroWindowSize通知,讓發送方暫時停止數據傳輸,并等待下一個確認通知。
下面我們來看看抓包中是如何體現窗口的特征的:
上圖是抓包工具抓到的一個ACK包的頭部信息,可以看出其windowsize的值是最大值,因為16bit的字段最大取值就是65535。紅框中下面那一行可能會讓大家疑惑。為什么會有一個Calculated window size呢?下面我們就來看一個TCP的選項:TCP Window Size Scaling。
1. 既然是選項,那么毫無疑問需要體現在上圖TCP報頭的選項(Options)字段。
2. 接下來我們再看一張抓包的截圖:
這張圖中我們可以看到,windows size的值是114,但是Calculated Windows Size的值卻是14592,這是怎么回事呢?
3. 在TCP三次握手過程中,可以通過SYN包開啟TCP選項Window Size Scaling,設計出這個選項是因為如今的帶寬已經大規模提升,千兆到桌面也是一件常事兒,因此,65535長度的窗口大小已經顯得有些小了,為了突破這個限制,便有了Window Size Scaling選項,看下圖SYN包截圖:
可以看到這個字段的值為7,也就是要將Window Size的值左移七位,即乘以128,因此,上圖中我們看到window size值是114,但是真正選用的值卻是14592(114*128)。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。