1.前言
TCP窗口縮放選項是用來增加TCP接收窗口的大小而超過65536字節。這個TCP選項以及其他的幾個選項在RFC1323(處理長肥管道網絡,LFN)中定義。
窗口縮放因子對於BDP大於64KB的時候的數據傳輸的效率非常有用。例如,如果一個T1傳輸鏈路,1.5Mbps是通過衛星的鏈路,RTT時間是513ms,那麼BDP是:1500000*.513 = 769,500位或者96,188字節。最大的64KB窗口僅僅允許填充鏈路緩衝區的68%或者是1.02Mbps。通過使用窗口擴大因子,文件傳輸可以接近 1.5Mbps,而充分利用可用帶寬。這個選現在慢速網絡上發送大於64KB的文件也是有用的。通過使用窗口擴大因子,接收窗口可能增加到最大1GB。
2.選項格式
RFC 1323中關於窗口擴大選項的圖示如下:
TCP Window Scale Option (WSopt): Kind: 3 Length: 3 bytes
+---------+---------+-------------+
| Kind=3 |Length=3 | shift.cnt |
+---------+---------+-------------+
3.工作過程
①要啓用窗口擴大選項,通訊雙方必須在各自的SYN報文中發送這個選項。主動建立連接的一方在SYN報文中發送這個選項;而被動建立連接的一方只有在收到帶窗口擴大選項的SYN報文之後才能發送這個選項。
②這個選項只在一個SYN報文中有意義(<SYN>或<SYN,ACK>),包含窗口擴大選項的報文如果沒有SYN位,則會被忽略掉。當連接建立起來後,在每個方向的擴大因子是固定的。注意:在SYN報文本身的窗口字段始終不做任何的擴大(The Window field in a SYN (i.e., a <SYN> or <SYN,ACK>) segment itself is never scaled.)。
③在啓用窗口擴大選項的情況下,若發送一個窗口通告,要將實際窗口大小右移shift.cnt位,然後賦給TCP首部中的16bit窗口值;而當接收到一個窗口通告時,則將TCP首部中的16bit窗口值左移shift.cnt位,以獲得實際的通告窗口大小。
④shift.cnt取值範圍爲0~14,即最大TCP序號限定爲2^16 * 2^ 14 = 2^30 < 2^31。該限制用於防止字節序列號溢出。
SACK選擇確認選項
1.前言
TCP通信時,如果發送序列中間某個數據包丟失,TCP會通過重傳最後確認的包開始的後續包,這樣原先已經正確傳輸的包也可能重複發送,急劇降低了TCP性能。爲改善這種情況,發展出SACK(Selective Acknowledgment, 選擇性確認)技術,使TCP只重新發送丟失的包,不用發送後續所有的包,而且提供相應機制使接收方能告訴發送方哪些數據丟失,哪些數據重發了,哪些數 據已經提前收到等。
2.選項格式
SACK信息是通過TCP頭的選項部分提供的,信息分兩種,一種標識是否支持SACK,是在TCP握手時發送;另一種是具體的SACK信息。
SACK允許選項
+---------+--------------+
| Kind=4 | Length=2 |
+---------+-------------+
該選項只允許在有SYN標誌的TCP包中,也即TCP握手的前兩個包中,分別表示各自是否支持SACK。
SACK選項
選項長度: 可變,但整個TCP選項長度不超過40字節,實際最多不超過4組邊界值。
+--------+--------+
| Kind=5 | Length |
+--------+--------+--------+-----------------+
| Left Edge of 1st Block |
+--------+--------+--------+-----------------+
| Right Edge of 1st Block |
+--------+--------+--------+-----------------+
| |
/ 。。。 . . . 。。。。。 /
| |
+--------+--------+--------+-----------------+
| Left Edge of nth Block |
+--------+--------+--------+----------------+
| Right Edge of nth Block |
+--------+--------+--------+----------------+
該選項參數告訴對方已經接收到並緩存的不連續的數據塊,注意都是已經接收的,發送方可根據此信息檢查究竟是哪個塊丟失,從而發送相應的數據塊。
* Left Edge of Block
不連續塊的第一個數據的序列號。
* Right Edge of Block
不連續塊的最後一個數據的序列號之後的序列號。表示(Left Edge - 1)和(Right Edge)處序列號的數據沒能接收到。
3.工作過程
SACK的產生
SACK通常都是由TCP接收方產生的,在TCP握手時如果接收到對方的SACK允許選項同時自己也支持SACK的話,在接收異常時就可以發送SACK包通知發送方。
對中間有丟包或延遲時的SACK
如果TCP接收方接收到非期待序列號的數據塊時,如果該塊的序列號小於期待的序列號,說明是網絡複製或重發的包,可以丟棄;如果收到的數據塊序列號大於期待的序列號,說明中間包被丟棄或延遲,此時可以發送SACK通知發送方出現了網絡丟包。
爲反映接收方的接收緩存和網絡傳輸情況,SACK中的第一個塊必須描述是那個數據塊激發此SACK選項的,接收方應該儘可能地在SACK選項部分中填寫儘可能多的塊信息,即使空間有限不能全部寫完,SACK選項中要報告最近接收的不連續數據塊,讓發送方能瞭解當前網絡傳輸情況的最新信息。
對重發包的SACK(D-SACK)
RFC2883中對SACK進行了擴展,在SACK中描述的是收到的數據段,這些數據段可以是正常的,也可能是重複發送的,SACK字段具有描述重複發送的數據段的能力,在第一塊SACK數據中描述重複接收的不連續數據塊的序列號參數,其他SACK數據則描述其他正常接收到的不連續數據,因此第一塊SACK描述的序列號會比後面的SACK描述的序列號大;而在接收到不完整的數據段的情況下,SACK範圍甚至可能小於當前的ACK值。通過這種方法,發送方可以更仔細判斷出當前網絡的傳輸情況,可以發現數據段被網絡複製、錯誤重傳、ACK丟失引起的重傳、重傳超時等異常的網絡狀況。
發送方對SACK的響應
TCP發送方都應該維護一個未確認的重發送數據隊列,數據未被確認前是不能釋放的,這個從重發送隊列中的每個數據塊都有一個標誌位“SACKed”標識是否該塊被SACK過,對於已經被SACK過的塊,在重新發送數據時將被跳過。發送方接收到接收方SACK信息後,根據SACK中數據標誌重發送隊列中相應的數據塊的“SACKed”標誌,但如果接收不到接收方數據,超時後,所有重發送隊列中數據塊的SACKed位都要清除,因爲可能接收方已經出現了異常。
4.應用舉例
發送方發送的數據 接收方接收的數據(包括SACK) 接收方發送的ACK
SACK累加接收的數據
5000-5499 (該包丟失)
5500-5999 5500-5999 5000, SACK=5500-6000
6000-6499 6000-6499 5000, SACK=5500-6500
6500-6999 6500-6999 5000, SACK=5500-7000
7000-7499 7000-7499 5000, SACK=5500-7500
數據包丟失,ACK丟失
3000-3499 3000-3499 3500 (ACK包丟失)
3500-3999 3500-3999 4000 (ACK包丟失)
4000-4499 (該包丟失)
4500-4999 4500-4999 4000, SACK=4500-5000 (ACK包丟失)
3000-3499 3000-3499 4000, SACK=3000-3500, 4500-5000
---------此爲D-SACK
數據段丟失和延遲
500-999 500-999 1000
1000-1499 (延遲)
1500-1999 (該包丟失)
2000-2499 2000-2499 1000, SACK=2000-2500
1000-2000 1000-1499 1500, SACK=2000-2500
1000-2000 2500, SACK=1000-1500
---------此爲D-SACK
數據段丟失且延遲
500-999 500-999 1000
1000-1499 (延遲)
1500-1999 (該包丟失)
2000-2499 (延遲)
2500-2999 (該包丟失)
3000-3499 3000-3499 1000, SACK=3000-3500
1000-2499 1000-1499 1500, SACK=3000-3500
2000-2499 1500, SACK=2000-2500, 3000-3500
1000-2499 2500, SACK=1000-1500, 3000-3500
---------此爲部分D-SACK
MSS: Maxitum Segment Size 最大分段大小
1.前言
最大報文段長度(M S S)表示T C P傳往另一端的最大塊數據的長度。當建立一個連接時,每一方都有用於通告它期望接收的 M S S選項(M S S選項只能出現在S Y N報文段中)。通過MSS,應用數據被分割成TCP認爲最適合發送的數據塊,由TCP傳遞給IP的信息單位稱爲報文段或段(segment)。
我們不難聯想到,跟最大報文段長度最爲相關的一個參數是網絡設備接口的MTU,以太網的MTU是1500,基本IP首部長度爲20,TCP首部是20,所以MSS的值可達1460(MSS不包括協議首部,只包含應用數據)。
2.選項格式
+---------+-----------+-------------+--------+
| Kind=2 |Length=4 | Mss值 |
+---------+-----------+-------------+--------+
3.工作過程
從上面我們可以看到,MSS是可以通過SYN段進行協商的(MSS選項只能出現在SYN報文段中),但它並不是任何條件下都可以協商的,如果一方不接受來自另一方的MSS值(不帶MMS選項即代表不接受),則MSS就定爲默認值536字節。
這裏有必要介紹路徑M T U的概念。路徑M T U當前在兩個主機之間的路徑上任何網絡上的最小M T U。路徑M T U的發現可以通過在I P首部中設置“不要分片( D F)”比特,來發現當前路徑上的路由器是否需要對正在發送的 I P數據報進行分片。如果一個待轉發的 I P數據報被設置D F比特,而其長度又超過了 M T U,那麼路由器將返回 I C M P不可達的差錯。
TCP的路徑MTU發現按如下方式進行:
①在連接建立時,TCP使用輸出接口或對端聲明的MSS中的最小MTU作爲起始的報文段大小。路徑 MTU發現不允許TCP超過對端聲明的MSS。如果對端沒有指定一個MSS,則默認爲536。
②一旦選定了起始的報文段大小,在該連接上的所有被 T C P發送的I P數據報都將被設置DF比特。如果某個中間路由器需要對一個設置了 D F標誌的數據報進行分片,它就丟棄這個數據報,併產生一個ICMP的“不能分片”差錯。
③如果收到這個ICMP差錯,TCP就減少段大小並進行重傳。如果路由器產生的是一個較新的該類ICMP差錯,則報文段大小被設置爲下一跳的 MTU減去IP和TCP的首部長度。如果是一個較舊的該類ICMP差錯,則必須嘗試下一個可能的最小 MTU。當由這個ICMP差錯引起的重傳發生時,擁塞窗口不需要變化,但要啓動慢啓動。
④由於路由可以動態變化,因此在最後一次減少路徑 M T U的一段時間以後,可以嘗試使用一個較大的值。
Timestamp時間戳選項
1.前言
時間戳選項使發送方在每個報文段中放置一個時間戳值。接收方在確認中返回這個數值,從而允許發送方爲每一個收到的 A C K計算RT T(我們必須說“每一個收到的 A C K”而不是“每一個報文段”,是因爲T C P通常用一個A C K來確認多個報文段)。我們提到過目前許多實現爲每一個窗口只計算一個 RT T,對於包含8個報文段的窗口而言這是正確的。然而,較大的窗口大小則需要進行更好的RT T計算。
2.選項格式
+---+-------+--------+-------+-------+-------+--------+------+--------+
| Kind=8 | Length=10 | 時間戳 | 時間戳回顯應答 |
+-----------------------------------+---------------------------------+
3.工作過程
時間戳是一個單調遞增的值。由於接收方只需要回顯收到的內容,因此不需要關注時間戳單元是什麼。這個選項不需要在兩個主機之間進行任何形式的時鐘同步。 RFC 1323推薦在1毫秒和1秒之間將時間戳的值加1。
在連接建立階段,對這個選項的規定與前一節講的窗口擴大選項類似。主動發起連接的一方在它的S Y N中指定選項。只有在它從另一方的 S Y N中收到了這個選項之後,該選項纔會在以後的報文段中進行設置。
我們已經看到接收方 T C P不需要對每個包含數據的報文段進行確認,許多實現每兩個報
文段發送一個A C K。如果接收方發送一個確認了兩個報文段的 A C K,那麼哪一個收到的時間 戳應當放入回顯應答字段中來發回去呢?
爲了減少任一端所維持的狀態數量,對於每個連接只保持一個時間戳的數值。選擇何時更新這個數值的算法非常簡單:
1) TCP跟蹤下一個A C K中將要發送的時間戳的值(一個名爲 t s re c e n t的變量)以及最後發送的A C K中的確認序號(一個名爲l a s t a c k的變量)。這個序號就是接收方期望的序號。
2) 當一個包含有字節號l a s t a c k的報文段到達時,則該報文段中的時間戳被保存在 t s re c e n t中。
3) 無論何時發送一個時間戳選項, t s re c e n t就作爲時間戳回顯應答字段被髮送,而序號字段被保存在l a s t a c k中。
Linux下相關的TCP參數配置
1. /proc/sys/net/core/rmem_max — 最大的TCP數據接收緩衝
2. /proc/sys/net/core/wmem_max — 最大的TCP數據發送緩衝
3. /proc/sys/net/ipv4/tcp_timestamps — 時間戳在(請參考RFC 1323)TCP的包頭增加12個字節
4. /proc/sys/net/ipv4/tcp_sack — 有選擇的應答
5. /proc/sys/net/ipv4/tcp_window_scaling — 支持更大的TCP窗口.
6. /proc/sys/net/core/rmem_default — 默認的接收窗口大小
7. /proc/sys/net/core/rmem_max — 接收窗口的最大大小
8. /proc/sys/net/core/wmem_default — 默認的發送窗口大小
9. /proc/sys/net/core/wmem_max — 發送窗口的最大大小
轉自:http://hi.baidu.com/clusterlee/blog/item/34870719dc53620e34fa4142.html