在TCP協(xié)議與”流”通信中芥牌,我們建立了滑窗(sliding window)的基本概念田篇。通過滑窗與ACK的配合,我們一方面實現(xiàn)了TCP傳輸?shù)目煽啃择帽伲硪环矫嬉惨欢ǔ潭壬咸岣吡诵省F涔ぷ鞣绞饺缦旅娴囊曨l所示:
視頻鏈接:http://v.youku.com/v_show/id_XNDg1NDUyMDUy.html
然而波附,之前的解釋只是概念性的艺晴。TCP為了達到更好的傳輸效率昼钻,對上面的工作方式進行了許多改進。The devil is in the details.?我們需要深入到細節(jié)封寞,才能看清楚TCP協(xié)議的智慧所在然评。
累計ACK
在TCP連接中,我們通過將ACK回復“附著”在其他數(shù)據(jù)片段的方式狈究,減少了ACK回復所消耗的流量碗淌。但這并不是全部的故事。TCP協(xié)議并不是對每個片段都發(fā)送ACK回復谦炒。TCP協(xié)議實際采用的是累計ACK回復(accumulative acknowledgement)贯莺。接收方往往利用一個ACK回復來知會連續(xù)多個片段的成功接收风喇。通過累計ACK宁改,所需要的ACK回復通常可以降到50%魂莫。
如下圖所示还蹲,橙色為已經接收的片段。方框為滑窗耙考,滑窗可容納3個片段谜喊。
累計ACK
滑窗還沒接收到片段7時,已接收到片段8倦始,9。這樣就在滑窗中制造了一個“空穴”(hole)。當滑窗最終接收到片段7時碎赢,滑窗送出一個回復號為10的ACK回復秒裕。發(fā)送方收到該回復,會意識到枚碗,片段10之前的片段已經按照次序被成功接收逾一。整個過程中節(jié)約了片段7和片段8所需的兩個ACK回復。
此外肮雨,接收方在接收到片斷遵堵,并應該回復ACK的時候,會故意延遲一些時間怨规。如果在延遲的時間里陌宿,有后續(xù)的片段到達,就可以利用累計ACK來一起回復了波丰。
滑窗結構
在之前的討論中限番,我們以片段為單位,來衡量滑窗的大小的呀舔。真實的滑窗是以byte為單位表示大小弥虐,但這并不會對我們之前的討論造成太大的影響扩灯。
發(fā)送方滑窗可以分為下面兩個部分。offered window為整個滑窗的大小霜瘪。
接收方滑窗可分為三個部分:
可以看到珠插,接收方的滑窗相對于發(fā)送方的滑窗多了一個“Received; ACKed; Not Sent to Proc”的部分。接收方接收到的文本流必須等待進程來讀取颖对。如果進程正忙于做別的事情捻撑,那么這些文本流即使已經正確接收,還是需要暫時占用接收緩存缤底。當出現(xiàn)上述占用時顾患,滑窗的可用部分(也就是圖中advertised window)就會縮水。這意味著接收方的處理能力下降个唧。如果這個時候發(fā)送方依然按照之前的速率發(fā)送數(shù)據(jù)給接收方江解,接收方將無力接收這些數(shù)據(jù)。
流量控制
TCP協(xié)議會根據(jù)情況自動改變滑窗大小徙歼,以實現(xiàn)流量控制犁河。流量控制(flow control)是指接收方將advertised window的大小通知給發(fā)送方,從而指導發(fā)送方修改offered window的大小魄梯。接收方將該信息放在TCP頭部的window size區(qū)域:
發(fā)送方在收到window size的通知時桨螺,會調整自己滑窗的大小,讓offered window和advertised window相符酿秸。這樣灭翔,發(fā)送窗口變小,文本流發(fā)送速率降低辣苏,從而減少了接收方的負擔肝箱。
零窗口
advertised window大小有可能變?yōu)?,這意味著接收方的接收能力降為0考润。發(fā)送方收到大小為0的advertised window通知時狭园,停止發(fā)送。
零窗口
當接收方經過處理糊治,再次產生可用的advertised window時唱矛,接收方會通過純粹的ACK回復來通知發(fā)送方,讓發(fā)送方恢復發(fā)送井辜。然而绎谦,ACK回復的傳送并不是可靠的。如果該ACK回復丟失粥脚,那么TCP傳輸將陷入死鎖(deadlock)狀態(tài)窃肠。
為此,發(fā)送方會在零窗口后刷允,不斷探測接收方的窗口冤留。窗口探測(window probe)時碧囊,發(fā)送方會向接收方發(fā)送包含1 byte文本流的TCP片段,并等待ACK回復(該ACK回復包含有window size)纤怒。由于有1 byte的數(shù)據(jù)存在糯而,所以該傳輸是可靠的,而不用擔心ACK回復丟失的問題泊窘。如果探測結果顯示窗口依然為0熄驼,發(fā)送方會等待更長的時間,然后再次進行窗口探測烘豹,直到TCP傳輸恢復瓜贾。
白癡窗口綜合癥
滑窗機制有可能犯病,比如白癡窗口綜合癥 (Silly Window Syndrome)携悯。假設這樣一種情形:接收方宣布(advertise)一個小的窗口祭芦,發(fā)送方根據(jù)advertised window,發(fā)送一個小的片段蚌卤。接收方的小窗口被填滿实束,經過處理奥秆,接收方再宣布一個小的窗口…… 這就是“白癡窗口綜合癥”:TCP通信的片段中包含的數(shù)據(jù)量很小逊彭。在這樣的情況下,TCP通信的片段所含的信息都很小构订,網(wǎng)絡流量主要是TCP片段的頭部侮叮,從而造成流量的浪費 (由于TCP頭部很大,我們希望每個TCP片段中含有比較多的數(shù)據(jù))悼瘾。
如果發(fā)送方不斷發(fā)送小的片段囊榜,也會造成“白癡窗口”。為了解決這個問題亥宿,需要從兩方面入手卸勺。TCP中有相關的規(guī)定,要求:
1. 接收方宣告的窗口必須達到一定的尺寸烫扼,否則等待曙求。
2. 除了一些特殊情況,發(fā)送方發(fā)送的片段必須達到一定的尺寸映企,否則等待悟狱。特殊情況主要是指需要最小化延遲的TCP應用(比如命令行互動)。
總結
累計ACK減少了TCP傳輸過程中所需的ACK流量堰氓。通過流量管理挤渐,TCP連接兩端的工作能力可以匹配,從而減少不不要的傳輸浪費双絮。累計ACK和流量控制都是TCP協(xié)議的重要特征浴麻。
TCP協(xié)議相當復雜得问,并充斥著各種細節(jié)。然而TCP協(xié)議又是如此重要的一個協(xié)議软免,引領風騷三十年椭赋,可以說是互聯(lián)網(wǎng)的奇跡。這些細節(jié)正是TCP協(xié)議成功的原因或杠,并值得我們深入了解哪怔。
【TCP/IP詳解】系列教程
TCP-IP協(xié)議詳解(1)網(wǎng)絡協(xié)議概觀
TCP-IP協(xié)議詳解(2) 以太網(wǎng)與WiFi協(xié)議
TCP-IP協(xié)議詳解(3) IP/ARP/RIP/BGP協(xié)議
TCP-IP協(xié)議詳解(6) ICMP協(xié)議
TCP-IP協(xié)議詳解(8) TCP協(xié)議與流通信
TCP-IP協(xié)議詳解(13) DNS協(xié)議