目前建立在TCP協(xié)議上的網(wǎng)絡(luò)協(xié)議特別多,,有telnet,,ssh,有ftp,,有http等等,。這些協(xié)議又可以根據(jù)數(shù)據(jù)吞吐量來大致分成兩大類:(1)交互數(shù)據(jù)類型,例如telnet,,ssh,,這種類型的協(xié)議在大多數(shù)情況下只是做小流量的數(shù)據(jù)交換,比如說按一下鍵盤,,回顯一些文字等等,。(2)數(shù)據(jù)成塊類型,例如ftp,,這種類型的協(xié)議要求TCP能盡量的運(yùn)載數(shù)據(jù),,把數(shù)據(jù)的吞吐量做到最大,并盡可能的提高效率,。針對這兩種情況,,TCP給出了兩種不同的策略來進(jìn)行數(shù)據(jù)傳輸。
1.TCP的交互數(shù)據(jù)流
對于交互性要求比較高的應(yīng)用,,TCP給出兩個策略來提高發(fā)送效率和減低網(wǎng)絡(luò)負(fù)擔(dān):(1)捎帶ACK,。(2)Nagle算法(一次盡量多的發(fā)數(shù)據(jù))。通常,,在網(wǎng)絡(luò)速度很快的情況下,,比如用lo接口進(jìn)行telnet通信,當(dāng)按下字母鍵并要求回顯的時候,,客戶端和服務(wù)器將經(jīng)歷 發(fā)送按鍵數(shù)據(jù)->服務(wù)器發(fā)送按鍵數(shù)據(jù)的ack -> 服務(wù)器端發(fā)送回顯數(shù)據(jù)->客戶端發(fā)送回顯數(shù)據(jù)的ACK的過程,,而其中的數(shù)據(jù)流量將是40bit + 41bit+41bit+40bit = 162bit,如果在廣域網(wǎng)里面,這種小分組的TCP流量將會造成很大的網(wǎng)絡(luò)負(fù)擔(dān),。
1.1.捎帶ACK的發(fā)送方式
這個策略是說,,當(dāng)主機(jī)收到遠(yuǎn)程主機(jī)的TCP數(shù)據(jù)報(bào)之后,通常不馬上發(fā)送ACK數(shù)據(jù)報(bào),,而是等上一個短暫的時間,,如果這段時間里面主機(jī)還有發(fā)送到遠(yuǎn)程主機(jī)的TCP數(shù)據(jù)報(bào),那么就把這個ACK數(shù)據(jù)報(bào)“捎帶”著發(fā)送出去,,把本來兩個TCP數(shù)據(jù)報(bào)整合成一個發(fā)送,。一般的,這個時間是200ms,??梢悦黠@地看到這個策略可以把TCP數(shù)據(jù)報(bào)的利用率提高很多。
1.2.Nagle算法
上過bbs的人應(yīng)該都會有感受,,就是在網(wǎng)絡(luò)慢的時候發(fā)貼,,有時鍵入一串字符串以后,經(jīng)過一段時間,,客戶端“發(fā)瘋”一樣突然回顯出很多內(nèi)容,,就好像數(shù)據(jù)一下子傳過來了一樣,這就是Nagle算法的作用,。
Nagle算法是說,,當(dāng)主機(jī)A給主機(jī)B發(fā)送了一個TCP數(shù)據(jù)報(bào)并進(jìn)入等待主機(jī)B的ACK數(shù)據(jù)報(bào)的狀態(tài)時,TCP的輸出緩沖區(qū)里面只能有一個TCP數(shù)據(jù)報(bào),,并且,,這個數(shù)據(jù)報(bào)不斷地收集后來的數(shù)據(jù),整合成一個大的數(shù)據(jù)報(bào),,等到B主機(jī)的ACK包一到,,就把這些數(shù)據(jù)“一股腦”的發(fā)送出去。雖然這樣的描述有些不準(zhǔn)確,,但還算形象和易于理解,,我們同樣可以體會到這個策略對于低減網(wǎng)絡(luò)負(fù)擔(dān)的好處。
在編寫插口程序的時候,,可以通過TCP_NODELAY來關(guān)閉這個算法,。并且,使用這個算法看情況的,,比如基于TCP的X窗口協(xié)議,,如果處理鼠標(biāo)事件時還是用這個算法,那么“延遲”可就非常大了,。
2.TCP的成塊數(shù)據(jù)流
對于FTP這樣對于數(shù)據(jù)吞吐量有較高要求的要求,,將總是希望每次盡量多的發(fā)送數(shù)據(jù)到對方主機(jī),,就算是有點(diǎn)“延遲”也無所謂。TCP也提供了一整套的策略來支持這樣的需求,。TCP協(xié)議中有16個bit表示“窗口”的大小,,這是這些策略的核心。
2.1.傳輸數(shù)據(jù)時ACK的問題
在解釋滑動窗口前,,需要看看ACK的應(yīng)答策略,一般來說,,發(fā)送端發(fā)送一個TCP數(shù)據(jù)報(bào),,那么接收端就應(yīng)該發(fā)送一個ACK數(shù)據(jù)報(bào)。但是事實(shí)上卻不是這樣,,發(fā)送端將會連續(xù)發(fā)送數(shù)據(jù)盡量填滿接受方的緩沖區(qū),,而接受方對這些數(shù)據(jù)只要發(fā)送一個ACK報(bào)文來回應(yīng)就可以了,這就是ACK的累積特性,,這個特性大大減少了發(fā)送端和接收端的負(fù)擔(dān),。
2.2.滑動窗口
滑動窗口本質(zhì)上是描述接受方的TCP數(shù)據(jù)報(bào)緩沖區(qū)大小的數(shù)據(jù),發(fā)送方根據(jù)這個數(shù)據(jù)來計(jì)算自己最多能發(fā)送多長的數(shù)據(jù),。如果發(fā)送方收到接受方的窗口大小為0的TCP數(shù)據(jù)報(bào),,那么發(fā)送方將停止發(fā)送數(shù)據(jù),等到接受方發(fā)送窗口大小不為0的數(shù)據(jù)報(bào)的到來,。書中的P211和P212很好的解釋了這一點(diǎn),。
關(guān)于滑動窗口協(xié)議,書上還介紹了三個術(shù)語,,分別是:
- 窗口合攏:當(dāng)窗口從左邊向右邊靠近的時候,,這種現(xiàn)象發(fā)生在數(shù)據(jù)被發(fā)送和確認(rèn)的時候。
- 窗口張開:當(dāng)窗口的右邊沿向右邊移動的時候,,這種現(xiàn)象發(fā)生在接受端處理了數(shù)據(jù)以后,。
- 窗口收縮:當(dāng)窗口的右邊沿向左邊移動的時候,這種現(xiàn)象不常發(fā)生,。
TCP就是用這個窗口,,慢慢的從數(shù)據(jù)的左邊移動到右邊,把處于窗口范圍內(nèi)的數(shù)據(jù)發(fā)送出去(但不用發(fā)送所有,,只是處于窗口內(nèi)的數(shù)據(jù)可以發(fā)送,。)。這就是窗口的意義,。圖20-6解釋了這一點(diǎn),。窗口的大小是可以通過socket來制定的,4096并不是最理想的窗口大小,,而16384則可以使吞吐量大大的增加,。
2.3.數(shù)據(jù)擁塞
上面的策略用于局域網(wǎng)內(nèi)傳輸還可以,但是用在廣域網(wǎng)中就可能會出現(xiàn)問題,最大的問題就是當(dāng)傳輸時出現(xiàn)了瓶頸(比如說一定要經(jīng)過一個slip低速鏈路)所產(chǎn)生的大量數(shù)據(jù)堵塞問題(擁塞),,為了解決這個問題,,TCP發(fā)送方需要確認(rèn)連接雙方的線路的數(shù)據(jù)最大吞吐量是多少。這,,就是所謂的擁塞窗口,。
擁塞窗口的原理很簡單,TCP發(fā)送方首先發(fā)送一個數(shù)據(jù)報(bào),,然后等待對方的回應(yīng),,得到回應(yīng)后就把這個窗口的大小加倍,然后連續(xù)發(fā)送兩個數(shù)據(jù)報(bào),,等到對方回應(yīng)以后,,再把這個窗口加倍(先是2的指數(shù)倍,到一定程度后就變成現(xiàn)行增長,,這就是所謂的慢啟動),,發(fā)送更多的數(shù)據(jù)報(bào),直到出現(xiàn)超時錯誤,,這樣,,發(fā)送端就了解到了通信雙方的線路承載能力,也就確定了擁塞窗口的大小,,發(fā)送方就用這個擁塞窗口的大小發(fā)送數(shù)據(jù),。要觀察這個現(xiàn)象是非常容易的,我們一般在下載數(shù)據(jù)的時候,,速度都是慢慢“沖起來的”
以上就是TCP數(shù)據(jù)傳輸?shù)拇笾铝鞒?,雖然并不細(xì)致,但是足以描述TCP的工作原理,,重點(diǎn)是TCP的流量控制原理,,滑動窗口,擁塞窗口,,ACK累計(jì)確認(rèn)等知識點(diǎn),。
|