第二十四章 :TCP的未來(lái)和性能

24.1 引言

TCP已經(jīng)在從1200 b/s的撥號(hào)SLIP鏈路到以太數(shù)據(jù)鏈路上運(yùn)行了許多年。在80年代和90年代初期,以太網(wǎng)是運(yùn)行TCP/IP最主要的數(shù)據(jù)鏈路方式。雖然TCP在比以太網(wǎng)速率高的環(huán)境(如T2電話線、FDDI及千兆比網(wǎng)絡(luò))中也能夠正確運(yùn)行,但在這些高速率環(huán)境下,TCP的某些限制就會(huì)暴露出來(lái)。

本章討論TCP的一些修改建議,這些建議可以使TCP在高速率環(huán)境中獲得最大的吞吐量。首先要討論前面已經(jīng)碰到過(guò)的路徑MTU發(fā)現(xiàn)機(jī)制,本章主要關(guān)注它如何與TCP協(xié)同工作。這個(gè)機(jī)制通??梢允筎CP為非本地的連接使用大于536字節(jié)的MTU,從而增加吞吐量。

接著介紹長(zhǎng)肥管道(long fat pipe),也就是那些具有很大的帶寬時(shí)延乘積的網(wǎng)絡(luò),以及TCP在這些網(wǎng)絡(luò)上所具有的局限性。為處理長(zhǎng)肥管道,我們描述兩個(gè)新的TCP選項(xiàng):窗口擴(kuò)大選項(xiàng)(用來(lái)增加TCP的最大窗口,使之超過(guò)65535字節(jié))和時(shí)間戳選項(xiàng)。后面這個(gè)選項(xiàng)可以使TCP對(duì)報(bào)文段進(jìn)行更加精確的RT T測(cè)量,還可以在高速率下對(duì)可能發(fā)生的序號(hào)回繞提供保護(hù)。這兩個(gè)選項(xiàng)在RFC 1323 [Jacobson,Braden,and Borman 1992]中進(jìn)行定義。

我們還將介紹建議的T/TCP,這是為增加事務(wù)功能而對(duì)TCP進(jìn)行的修改。通信的事務(wù)模式以客戶的請(qǐng)求將被服務(wù)器應(yīng)答的響應(yīng)為主要特征。這是客戶服務(wù)器計(jì)算的常見模型。T/TCP的目的就是減少兩端交換的報(bào)文段數(shù)量,避免三次握手和使用4個(gè)報(bào)文段進(jìn)行連接的關(guān)閉,從而使客戶可以在一個(gè)RT T和處理請(qǐng)求所必需的時(shí)間內(nèi)收到服務(wù)器的應(yīng)答。

這些新選項(xiàng)(路徑MTU發(fā)現(xiàn)、窗口擴(kuò)大選項(xiàng)、時(shí)間戳選項(xiàng)和T/TCP)中令人印象最深刻的就是它們與現(xiàn)有的TCP實(shí)現(xiàn)能夠向后兼容,即包括這些新選項(xiàng)的系統(tǒng)仍然可以與原有的舊系統(tǒng)進(jìn)行交互。除了在一個(gè)ICMP報(bào)文中為路徑MTU發(fā)現(xiàn)增加了一個(gè)額外字段之外,這些新的選項(xiàng)只需要在那些需要使用它們的端系統(tǒng)中進(jìn)行實(shí)現(xiàn)。

我們以介紹近來(lái)發(fā)表的有關(guān)TCP性能的圖例作為本章的結(jié)束。

24.2 路徑MTU發(fā)現(xiàn)

在2.9節(jié)我們描述了路徑MTU的概念。這是當(dāng)前在兩個(gè)主機(jī)之間的路徑上任何網(wǎng)絡(luò)上的最小MTU。路徑MTU發(fā)現(xiàn)在IP首部中繼承并設(shè)置“不要分片(DF)”比特,來(lái)發(fā)現(xiàn)當(dāng)前路徑上的路由器是否需要對(duì)正在發(fā)送的IP數(shù)據(jù)報(bào)進(jìn)行分片。在11.6節(jié)我們觀察到如果一個(gè)待轉(zhuǎn)發(fā)的IP數(shù)據(jù)報(bào)被設(shè)置DF比特,而其長(zhǎng)度又超過(guò)了MTU,那么路由器將返回ICMP不可達(dá)的差錯(cuò)。在11.7節(jié)我們顯示了某版本的traceroute程序使用該機(jī)制來(lái)決定目的地的路徑MTU。在11.8節(jié)我們看到UDP是怎樣處理路徑MTU發(fā)現(xiàn)的。在本節(jié)我們將討論這個(gè)機(jī)制是如何按照RFC 1191 [Mogul and Deering 1990]中規(guī)定的那樣在TCP中進(jìn)行使用的。

在本書的多種系統(tǒng)(參看序言)中只有Solaris 2.x支持路徑MTU發(fā)現(xiàn)。

TCP的路徑MTU發(fā)現(xiàn)按如下方式進(jìn)行:在連接建立時(shí),TCP使用輸出接口或?qū)Χ寺暶鞯腗SS中的最小MTU作為起始的報(bào)文段大小。路徑MTU發(fā)現(xiàn)不允許TCP超過(guò)對(duì)端聲明的MSS。如果對(duì)端沒有指定一個(gè)MSS,則默認(rèn)為536。一個(gè)實(shí)現(xiàn)也可以按21.9節(jié)中講的那樣為每個(gè)路由單獨(dú)保存路徑MTU信息。

一旦選定了起始的報(bào)文段大小,在該連接上的所有被TCP發(fā)送的IP數(shù)據(jù)報(bào)都將被設(shè)置DF比特。如果某個(gè)中間路由器需要對(duì)一個(gè)設(shè)置了DF標(biāo)志的數(shù)據(jù)報(bào)進(jìn)行分片,它就丟棄這個(gè)數(shù)據(jù)報(bào),并產(chǎn)生一個(gè)我們?cè)?1.6節(jié)介紹的ICMP的“不能分片”差錯(cuò)。

如果收到這個(gè)ICMP差錯(cuò),TCP就減少段大小并進(jìn)行重傳。如果路由器產(chǎn)生的是一個(gè)較新的該類ICMP差錯(cuò),則報(bào)文段大小被設(shè)置為下一跳的MTU減去IP和TCP的首部長(zhǎng)度。如果是一個(gè)較舊的該類ICMP差錯(cuò),則必須嘗試下一個(gè)可能的最小MTU(見圖2-5)。當(dāng)由這個(gè)ICMP差錯(cuò)引起的重傳發(fā)生時(shí),擁塞窗口不需要變化,但要啟動(dòng)慢啟動(dòng)。

由于路由可以動(dòng)態(tài)變化,因此在最后一次減少路徑MTU的一段時(shí)間以后,可以嘗試使用一個(gè)較大的值(直到等于對(duì)端聲明的MSS或輸出接口MTU的最小值)。RFC 1191推薦這個(gè)時(shí)間間隔為10分鐘(我們?cè)?1.8節(jié)看到Solaris 2.2使用一個(gè)30分鐘的時(shí)間間隔)。

在對(duì)非本地目的地,默認(rèn)的MSS通常為536字節(jié),路徑MTU發(fā)現(xiàn)可以避免在通過(guò)MTU小于576(這非常罕見)的中間鏈路時(shí)進(jìn)行分片。對(duì)于本地目的主機(jī),也可以避免在中間鏈路(如以太網(wǎng))的MTU小于端點(diǎn)網(wǎng)絡(luò)(如令牌環(huán)網(wǎng))的情況下進(jìn)行分片。但為了能使路徑MTU更加有用和充分利用MTU大于576的廣域網(wǎng),一個(gè)實(shí)現(xiàn)必須停止使用為非本地目的制定的536的MTU默認(rèn)值。MSS的一個(gè)較好的選擇是輸出接口的MTU(當(dāng)然要減去IP和TCP的首部大小)(在附錄E中,我們將看到大多數(shù)的實(shí)現(xiàn)都允許系統(tǒng)管理員改變這個(gè)默認(rèn)的MSS值)。

24.2.1 一個(gè)例子

在某個(gè)中間路由器的MTU比任一個(gè)端點(diǎn)接口MTU小的情況下,我們能夠觀察路徑MTU發(fā)現(xiàn)是如何工作的。圖24-1顯示了這個(gè)例子的拓?fù)浣Y(jié)構(gòu)。

圖24-1 路徑MTU例子的拓?fù)浣Y(jié)構(gòu)

我們從主機(jī)solaris(支持路徑MTU發(fā)現(xiàn)機(jī)制)到主機(jī)slip建立一個(gè)連接。這個(gè)建立過(guò)程與UDP的路徑MTU發(fā)現(xiàn)(圖11-13)中的一個(gè)例子相同,但在這里我們已經(jīng)把slip接口的MTU設(shè)置為552,而不是通常的296。這使得slip通告一個(gè)512的MSS。但是在bsdi上的SLIP鏈路上的MTU為296,這就引起超過(guò)256的TCP報(bào)文段被分片。于是就可以觀察在solaris上的路徑MTU發(fā)現(xiàn)是如何進(jìn)行處理的。

我們?cè)趕olaris上運(yùn)行sock程序并向slip上的丟棄服務(wù)器進(jìn)行一個(gè)512字節(jié)的寫操作:

solaris % sock -i -n1 -w512 slip discard

圖24-2是在主機(jī)sun的SLIP接口上收集的tcpdump的輸出結(jié)果。

圖24-2 路徑MTU發(fā)現(xiàn)的tcpdump輸出結(jié)果

在第1和第2行的MSS值是我們所期望的。接著我們觀察到solaris發(fā)送一個(gè)包含512字節(jié)的數(shù)據(jù)和對(duì)SYN的確認(rèn)報(bào)文段(第3行)(在習(xí)題18.9中可以看到這種把SYN的確認(rèn)與第一個(gè)包含數(shù)據(jù)的報(bào)文段合并的情況)。這就在第4行產(chǎn)生了一個(gè)ICMP差錯(cuò),我們看到路由器bsdi產(chǎn)生較新的、包含輸出接口MTU的ICMP差錯(cuò)。

看來(lái)在這個(gè)差錯(cuò)回到solaris之前,就發(fā)送了FIN(第5行)。由于slip從沒有收到被路由器bsdi丟棄的512字節(jié)的數(shù)據(jù),因此并不期望接收這個(gè)序號(hào)(513),所以在第6行用它期望的序號(hào)(1)進(jìn)行了響應(yīng)。

在這個(gè)時(shí)候,ICMP差錯(cuò)返回到了solaris,solaris用兩個(gè)256字節(jié)的報(bào)文段(第7和第9行)重傳了512字節(jié)的數(shù)據(jù)。因?yàn)樵赽sdi后面可能還有具有更小的MTU的路由器,因此這兩個(gè)報(bào)文段都設(shè)置了DF比特。

接著是一個(gè)較長(zhǎng)的傳輸過(guò)程(持續(xù)了大約15分鐘),在最初的512字節(jié)變?yōu)?56字節(jié)以后,solaris沒有再嘗試使用更大的報(bào)文段。

24.2.2 大分組還是小分組

常規(guī)知識(shí)告訴我們較大的分組比較好 [Mogul 1993,15.2.8節(jié)],因?yàn)榘l(fā)送較少的大分組比發(fā)送較多的小分組“花費(fèi)”要少(假定分組的大小不足以引起分片,否則會(huì)引起其他方面的問(wèn)題)。這些減少的花費(fèi)與網(wǎng)絡(luò)(分組首部負(fù)荷)、路由器(選路的決定)和主機(jī)(協(xié)議處理和設(shè)備中斷)等有關(guān)。但并非所有的人都同意這種觀點(diǎn) [Bellovin 1993]。

考慮下面的例子。我們通過(guò)4個(gè)路由器發(fā)送8192個(gè)字節(jié),每個(gè)路由器與一個(gè)T1電話線(1544 000b/s)相連。首先我們使用兩個(gè)4096字節(jié)的分組,如圖24-3所示。

圖24-3 通過(guò)4個(gè)路由器發(fā)送兩個(gè)4096字節(jié)的分組

基本問(wèn)題在于路由器是存儲(chǔ)轉(zhuǎn)發(fā)設(shè)備。它們通常接收整個(gè)輸入分組,檢驗(yàn)包含IP檢驗(yàn)和的IP首部,進(jìn)行選路判決,然后開始發(fā)送輸出分組。在這個(gè)圖中,我們可以假定在理想情況下這些在路由器內(nèi)部進(jìn)行的操作不花費(fèi)時(shí)間(水平點(diǎn)狀線)。然而,從R1到R4它需要花費(fèi)4個(gè)單位時(shí)間來(lái)發(fā)送所有的8192字節(jié)。每一跳的時(shí)間為

(將TCP和IP的首部算為40字節(jié))。發(fā)送數(shù)據(jù)的整個(gè)時(shí)間為分組個(gè)數(shù)加上跳數(shù)減1,從圖中可以看到是4個(gè)單位時(shí)間,或85.6秒。每個(gè)鏈路空閑2個(gè)單位時(shí)間,或42.8秒。

圖24-4顯示了當(dāng)我們發(fā)送16個(gè)512字節(jié)的分組時(shí)所發(fā)生的情況。

圖24-4 通過(guò)4個(gè)路由器發(fā)送16個(gè)512字節(jié)的分組

這將花費(fèi)更多的單位時(shí)間,但是由于發(fā)送的分組較短,因此每個(gè)單位時(shí)間較小。


現(xiàn)在總時(shí)間為(18×2.9)=52.2 ms。每個(gè)鏈路也空閑2個(gè)單位的時(shí)間,即5.8 ms。

在這個(gè)例子中,我們忽略了確認(rèn)返回所需要的時(shí)間、連接建立和終止以及鏈路可能被其他流量共享等的影響。然而,在[Bellovin 1993]中的測(cè)量表明,分組并不一定是越大越好。我們需要在更多的網(wǎng)絡(luò)上對(duì)該領(lǐng)域進(jìn)行更多的研究。

24.3 長(zhǎng)肥管道

在20.7節(jié),我們把一個(gè)連接的容量表示為

capacity(b) = bandwidth(b/s) × round - triptime(s)

并稱之為帶寬時(shí)延乘積。也可稱它為兩端的管道大小。

當(dāng)這個(gè)乘積變得越來(lái)越大時(shí),TCP的某些局限性就會(huì)暴露出來(lái)。圖24-5顯示了多種類型的網(wǎng)絡(luò)的某些數(shù)值。

圖24-5 多種網(wǎng)絡(luò)的帶寬時(shí)延乘積

可以看到帶寬時(shí)延乘積的單位是字節(jié),這是因?yàn)槲覀冇眠@個(gè)單位來(lái)測(cè)量每一端的緩存大小和窗口大小。

具有大的帶寬時(shí)延乘積的網(wǎng)絡(luò)被稱為長(zhǎng)肥網(wǎng)絡(luò)(Long Fat Network,即LFN,發(fā)音為“elefan(t)s”),而一個(gè)運(yùn)行在LFN上的TCP連接被稱為長(zhǎng)肥管道?;仡檲D20-11和圖20-12,管道可以被水平拉長(zhǎng)(一個(gè)長(zhǎng)的RT T),或被垂直拉高(較高的帶寬),或向兩個(gè)方向拉伸。使用長(zhǎng)肥管道會(huì)遇到多種問(wèn)題。

1:TCP首部中窗口大小為16 bit,從而將窗口限制在65535個(gè)字節(jié)內(nèi)。但是從圖24-5的最后一列可以看到,現(xiàn)有的網(wǎng)絡(luò)需要一個(gè)更大的窗口來(lái)提供最大的吞吐量。在24.4節(jié)介紹的窗口擴(kuò)大選項(xiàng)可以解決這個(gè)問(wèn)題。

2:在一個(gè)長(zhǎng)肥網(wǎng)絡(luò)LFN內(nèi)的分組丟失會(huì)使吞吐量急劇減少。如果只有一個(gè)報(bào)文段丟失,我們需要利用21.7節(jié)介紹的快速重傳和快速恢復(fù)算法來(lái)使管道避免耗盡。但是即使使用這些算法,在一個(gè)窗口內(nèi)發(fā)生的多個(gè)分組丟失也會(huì)典型地使管道耗盡(如果管道耗盡了,慢啟動(dòng)會(huì)使它漸漸填滿,但這個(gè)過(guò)程將需要經(jīng)過(guò)多個(gè)RTT)。
在RFC 1072 [Jacobson and Braden 1988]中建議使用有選擇的確認(rèn)(SACK)來(lái)處理在一個(gè)窗口發(fā)生的多個(gè)分組丟失。但是這個(gè)功能在RFC 1323中被忽略了,因?yàn)樽髡哂X得在把它們納入TCP之前需要先解決一些技術(shù)上的問(wèn)題。

3:我們?cè)诘?1.4節(jié)看到許多TCP實(shí)現(xiàn)對(duì)每個(gè)窗口的RTT僅進(jìn)行一次測(cè)量。它們并不對(duì)每個(gè)報(bào)文段進(jìn)行RTT測(cè)量。在一個(gè)長(zhǎng)肥網(wǎng)絡(luò)LFN上需要更好的RTT測(cè)量機(jī)制。我們將在24.5節(jié)介紹時(shí)間戳選項(xiàng),它允許更多的報(bào)文段被計(jì)時(shí),包括重傳。

4:TCP對(duì)每個(gè)字節(jié)數(shù)據(jù)使用一個(gè)32 bit無(wú)符號(hào)的序號(hào)來(lái)進(jìn)行標(biāo)識(shí)。如果在網(wǎng)絡(luò)中有一個(gè)被延遲一段時(shí)間的報(bào)文段,它所在的連接已被釋放,而一個(gè)新的連接在這兩個(gè)主機(jī)之間又建立了,怎樣才能防止這樣的報(bào)文段再次出現(xiàn)呢?首先回想起IP首部中的TTL為每個(gè)IP段規(guī)定了一個(gè)生存時(shí)間的上限—255跳或255秒,看哪一個(gè)上限先達(dá)到。在18.6節(jié)我們定義了最大的報(bào)文段生存時(shí)間(MSL)作為一個(gè)實(shí)現(xiàn)的參數(shù)來(lái)阻止這種情況的發(fā)生。推薦的MSL的值為2分鐘(給出一個(gè)240秒的2MSL),但是我們?cè)?8.6節(jié)看到許多實(shí)現(xiàn)使用的MSL為30秒。

在長(zhǎng)肥網(wǎng)絡(luò)LFN上,TCP的序號(hào)會(huì)碰到一個(gè)不同的問(wèn)題。由于序號(hào)空間是有限的,在已經(jīng)傳輸了4294 967 296個(gè)字節(jié)以后序號(hào)會(huì)被重用。如果一個(gè)包含序號(hào)N字節(jié)數(shù)據(jù)的報(bào)文段在網(wǎng)絡(luò)上被遲延并在連接仍然有效時(shí)又出現(xiàn),會(huì)發(fā)生什么情況呢?這僅僅是一個(gè)相同序號(hào)N在MSL期間是否被重用的問(wèn)題,也就是說(shuō),網(wǎng)絡(luò)是否足夠快以至于在不到一個(gè)MSL的時(shí)候序號(hào)就發(fā)生了回繞。在一個(gè)以太網(wǎng)上要發(fā)送如此多的數(shù)據(jù)通常需要60分鐘左右,因此不會(huì)發(fā)生這種情況。但是在帶寬增加時(shí),這個(gè)時(shí)間將會(huì)減少:一個(gè)T3的電話線(45 Mb/s)在12分鐘內(nèi)會(huì)發(fā)生回繞,F(xiàn)DDI(100 Mb/s)為5分鐘,而一個(gè)千兆比網(wǎng)絡(luò)(1000 Mb/s)則為34秒。這時(shí)問(wèn)題不再是帶寬時(shí)延乘積,而在于帶寬本身。
在24.6節(jié),我們將介紹一種對(duì)付這種情況的辦法:使用TCP的時(shí)間戳選項(xiàng)的PAW S(Protection Against Wrapped Sequence numbers)算法(保護(hù)回繞的序號(hào))。

4.4BSD包含了我們將要在下面介紹的所有選項(xiàng)和算法:窗口擴(kuò)大選項(xiàng)、時(shí)間戳選項(xiàng)和保護(hù)回繞的序號(hào)。許多供應(yīng)商也正在開始支持這些選項(xiàng)

千兆比網(wǎng)絡(luò)

當(dāng)網(wǎng)絡(luò)的速率達(dá)到千兆比的時(shí)候,情況就會(huì)發(fā)生變化。[Partridge 1994]詳細(xì)介紹了千兆比網(wǎng)絡(luò)。在這里我們看一下在時(shí)延和帶寬之間的差別 [Kleinrock 1992]。

考慮通過(guò)美國(guó)發(fā)送一個(gè)100萬(wàn)字節(jié)的文件的情況,假定時(shí)延為30 ms。圖24-6顯示了兩種情況:上圖顯示了使用一個(gè)T1電話線(1544 000 b/s)的情況,而下圖則是使用一個(gè)1Gb/s網(wǎng)絡(luò)的情況。x軸顯示的是時(shí)間,發(fā)送方在圖的左側(cè),而接收方則在圖的右側(cè),y軸為網(wǎng)絡(luò)容量。兩幅圖中的陰影區(qū)域表示發(fā)送的100萬(wàn)字節(jié)。

圖24-6 以30 ms的延時(shí)通過(guò)網(wǎng)絡(luò)發(fā)送100萬(wàn)字節(jié)的文件

圖24-6顯示了30 ms后這兩個(gè)網(wǎng)絡(luò)的狀態(tài)。經(jīng)過(guò)30 ms(延時(shí))以后數(shù)據(jù)的第1個(gè)比特都已到達(dá)對(duì)端。但對(duì)T1網(wǎng)絡(luò)而言,由于管道容量?jī)H為5790字節(jié),因此發(fā)送方仍然有994 210個(gè)字節(jié)等待發(fā)送。而千兆比網(wǎng)絡(luò)的容量則為3750 000字節(jié),因此,整個(gè)文件僅使用了25%左右的帶寬,此時(shí)文件的最后一個(gè)比特已經(jīng)到達(dá)第1個(gè)字節(jié)后8ms處。

經(jīng)過(guò)T1網(wǎng)絡(luò)傳輸文件的總時(shí)間為5.211秒。如果增加更多的帶寬,使用一個(gè)T3網(wǎng)絡(luò)(45 000 000 b/s),則總時(shí)間減少到0.208秒。增加約29倍的帶寬可以將總時(shí)間減小到約25分之一。

使用千兆比網(wǎng)絡(luò)傳輸文件的總時(shí)間為0.038秒:30 ms的時(shí)延加上8ms的真正傳輸文件的時(shí)間。假定能夠?qū)捲黾訛?000 Mb/s,我們只能夠?qū)⒖倳r(shí)間減小為0.304 ms:同樣30 ms的時(shí)延和4ms的真正傳輸時(shí)間?,F(xiàn)在使帶寬加倍僅能夠?qū)r(shí)間減少約10%。在千兆比速率下,時(shí)延限制占據(jù)了主要地位,而帶寬不再成為限制。

時(shí)延主要是由光速引起的,而且不能夠被減小(除非愛因斯坦是錯(cuò)誤的)。當(dāng)我們考慮到分組需要建立和終止一個(gè)連接時(shí),這個(gè)固定時(shí)延起的作用就更糟糕了。千兆比網(wǎng)絡(luò)會(huì)引起一些需要不同看待的連網(wǎng)觀點(diǎn)。

24.4 窗口擴(kuò)大選項(xiàng)

窗口擴(kuò)大選項(xiàng)使TCP的窗口定義從16 bit增加為32 bit。這并不是通過(guò)修改TCP首部來(lái)實(shí)現(xiàn)的,TCP首部仍然使用16 bit,而是通過(guò)定義一個(gè)選項(xiàng)實(shí)現(xiàn)對(duì)16 bit的擴(kuò)大操作(scaling operation)來(lái)完成的。于是TCP在內(nèi)部將實(shí)際的窗口大小維持為32 bit的值。

在圖18-20可以看到關(guān)于這個(gè)選項(xiàng)的例子。一個(gè)字節(jié)的移位記數(shù)器取值為0(沒有擴(kuò)大窗口的操作)和14。這個(gè)最大值14表示窗口大小為1073 725 440字節(jié)(65535×214)。

這個(gè)選項(xiàng)只能夠出現(xiàn)在一個(gè)SYN報(bào)文段中,因此當(dāng)連接建立起來(lái)后,在每個(gè)方向的擴(kuò)大因子是固定的。為了使用窗口擴(kuò)大,兩端必須在它們的SYN報(bào)文段中發(fā)送這個(gè)選項(xiàng)。主動(dòng)建立連接的一方在其SYN中發(fā)送這個(gè)選項(xiàng),但是被動(dòng)建立連接的一方只能夠在收到帶有這個(gè)選項(xiàng)的SYN之后才可以發(fā)送這個(gè)選項(xiàng)。每個(gè)方向上的擴(kuò)大因子可以不同。

如果主動(dòng)連接的一方發(fā)送一個(gè)非零的擴(kuò)大因子,但是沒有從另一端收到一個(gè)窗口擴(kuò)大選項(xiàng),它就將發(fā)送和接收的移位記數(shù)器置為0。這就允許較新的系統(tǒng)能夠與較舊的、不理解新選項(xiàng)的系統(tǒng)進(jìn)行互操作。

Host Requirements RFC要求TCP接受在任何報(bào)文段中的一個(gè)選項(xiàng)(只有前面定義的一個(gè)選項(xiàng),即最大報(bào)文段大小,僅在SYN報(bào)文段中出現(xiàn))。它還進(jìn)一步要求TCP忽略任何它不理解的選項(xiàng)。這就使事情變得容易,因?yàn)樗行碌倪x項(xiàng)都有一個(gè)長(zhǎng)度字段(圖18-20)。

假定我們正在使用窗口擴(kuò)大選項(xiàng),發(fā)送移位記數(shù)為S,而接收移位記數(shù)則為R。于是我們從另一端收到的每一個(gè)16 bit的通告窗口將被左移R位以獲得實(shí)際的通告窗口大小。每次當(dāng)我們向?qū)Ψ桨l(fā)送一個(gè)窗口通告的時(shí)候,我們將實(shí)際的32 bit窗口大小右移S比特,然后用它來(lái)替換TCP首部中的16 bit的值。

TCP根據(jù)接收緩存的大小自動(dòng)選擇移位計(jì)數(shù)。這個(gè)大小是由系統(tǒng)設(shè)置的,但是通常向應(yīng)用進(jìn)程提供了修改途徑(我們?cè)?0.4節(jié)中討論了這個(gè)緩存)。

一個(gè)例子

如果在4.4BSD的主機(jī)vangogh.cs.berkeley.edu上使用sock程序來(lái)初始化一個(gè)連接,我們可以觀察到它的TCP計(jì)算窗口擴(kuò)大因子的情況。下面的交互輸出顯示的是兩個(gè)連續(xù)運(yùn)行的程序,第1個(gè)指定接收緩存為128 000字節(jié),而第2個(gè)的緩存則為220 000字節(jié)。

圖24-7 顯示了這兩個(gè)連接的tcpdump輸出結(jié)果(去掉了第2個(gè)連接的最后8行,因?yàn)闆]有什么新內(nèi)容)。
圖24-7 窗口擴(kuò)大選項(xiàng)的例子

在第1行,vangogh通告一個(gè)65535的窗口,并通過(guò)設(shè)置移位計(jì)數(shù)為1來(lái)指明窗口擴(kuò)大選項(xiàng)。這個(gè)通告的窗口是比接收窗口(128 000)還小的一個(gè)最大可能取值,因?yàn)樵谝粋€(gè)SYN報(bào)文段中的窗口字段從不進(jìn)行擴(kuò)大運(yùn)算。

擴(kuò)大因子為1表示vangogh發(fā)送窗口通告一直到131 070(65535×21)。這將調(diào)節(jié)我們的接收緩存的大?。?2 8000)。因?yàn)閎sdi在它的SYN(第2行)中沒有發(fā)送窗口擴(kuò)大選項(xiàng),因此這個(gè)選項(xiàng)沒有被使用。注意到vangogh在隨后的連接階段繼續(xù)使用最大可能的窗口(65535)。

對(duì)于第2個(gè)連接vangogh請(qǐng)求的移位計(jì)數(shù)為2,表明它希望發(fā)送窗口通告一直為262 140(65535×22),這比我們的接收緩存(220 000)大。

24.5 時(shí)間戳選項(xiàng)

時(shí)間戳選項(xiàng)使發(fā)送方在每個(gè)報(bào)文段中放置一個(gè)時(shí)間戳值。接收方在確認(rèn)中返回這個(gè)數(shù)值,從而允許發(fā)送方為每一個(gè)收到的ACK計(jì)算RTT(我們必須說(shuō)“每一個(gè)收到的ACK”而不是“每一個(gè)報(bào)文段”,是因?yàn)門CP通常用一個(gè)ACK來(lái)確認(rèn)多個(gè)報(bào)文段)。我們提到過(guò)目前許多實(shí)現(xiàn)為每一個(gè)窗口只計(jì)算一個(gè)RTT,對(duì)于包含8個(gè)報(bào)文段的窗口而言這是正確的。然而,較大的窗口大小則需要進(jìn)行更好的RTT計(jì)算。

RFC 1323的3.1節(jié)給出了需要為較大窗口進(jìn)行更好的RTT計(jì)算的信號(hào)處理的理由。通常RTT通過(guò)對(duì)一個(gè)數(shù)據(jù)信號(hào)(包含數(shù)據(jù)的報(bào)文段)以較低的頻率(每個(gè)窗口一次)進(jìn)行采樣來(lái)進(jìn)行計(jì)算,這就將別名引入了被估計(jì)的RTT中。當(dāng)每個(gè)窗口中有8個(gè)報(bào)文段時(shí),采樣速率為數(shù)據(jù)率的1/8,這還是可以忍受的。但是如果每個(gè)窗口中有100個(gè)報(bào)文段時(shí),采樣速率則為數(shù)據(jù)速率的1/100,這將導(dǎo)致被估計(jì)的RTT不精確,從而引起不必要的重傳。如果一個(gè)報(bào)文段被丟失,則會(huì)使情況變得更糟。

圖18-20顯示了時(shí)間戳選項(xiàng)的格式。發(fā)送方在第1個(gè)字段中放置一個(gè)32 bit的值,接收方在應(yīng)答字段中回顯這個(gè)數(shù)值。包含這個(gè)選項(xiàng)的TCP首部長(zhǎng)度將從正常的20字節(jié)增加為32字節(jié)。

時(shí)間戳是一個(gè)單調(diào)遞增的值。由于接收方只需要回顯收到的內(nèi)容,因此不需要關(guān)注時(shí)間戳單元是什么。這個(gè)選項(xiàng)不需要在兩個(gè)主機(jī)之間進(jìn)行任何形式的時(shí)鐘同步。RFC 1323推薦在1毫秒和1秒之間將時(shí)間戳的值加1。

4.4BSD在啟動(dòng)時(shí)將時(shí)間戳始終設(shè)置為0,然后每隔500 ms將時(shí)間戳?xí)r鐘加1。

在圖24-7中,如果觀察在報(bào)文段1和報(bào)文段11的時(shí)間戳,它們之間的差(89個(gè)單元)對(duì)應(yīng)于每個(gè)單元500 ms的規(guī)定,因?yàn)閷?shí)際時(shí)間差為44.4秒。

在連接建立階段,對(duì)這個(gè)選項(xiàng)的規(guī)定與前一節(jié)講的窗口擴(kuò)大選項(xiàng)類似。主動(dòng)發(fā)起連接的一方在它的SYN中指定選項(xiàng)。只有在它從另一方的SYN中收到了這個(gè)選項(xiàng)之后,該選項(xiàng)才會(huì)在以后的報(bào)文段中進(jìn)行設(shè)置。

我們已經(jīng)看到接收方TCP不需要對(duì)每個(gè)包含數(shù)據(jù)的報(bào)文段進(jìn)行確認(rèn),許多實(shí)現(xiàn)每?jī)蓚€(gè)報(bào)文段發(fā)送一個(gè)ACK。如果接收方發(fā)送一個(gè)確認(rèn)了兩個(gè)報(bào)文段的ACK,那么哪一個(gè)收到的時(shí)間戳應(yīng)當(dāng)放入回顯應(yīng)答字段中來(lái)發(fā)回去呢?

為了減少任一端所維持的狀態(tài)數(shù)量,對(duì)于每個(gè)連接只保持一個(gè)時(shí)間戳的數(shù)值。選擇何時(shí)更新這個(gè)數(shù)值的算法非常簡(jiǎn)單:

1:TCP跟蹤下一個(gè)ACK中將要發(fā)送的時(shí)間戳的值(一個(gè)名為tsrecent的變量)以及最后發(fā)送的ACK中的確認(rèn)序號(hào)(一個(gè)名為lastack的變量)。這個(gè)序號(hào)就是接收方期望的序號(hào)。

2:當(dāng)一個(gè)包含有字節(jié)號(hào)lastack的報(bào)文段到達(dá)時(shí),則該報(bào)文段中的時(shí)間戳被保存在tsrecent中。

3:無(wú)論何時(shí)發(fā)送一個(gè)時(shí)間戳選項(xiàng),tsrecent就作為時(shí)間戳回顯應(yīng)答字段被發(fā)送,而序號(hào)字段被保存在lastack中。

這個(gè)算法能夠處理下面兩種情況:

1:如果ACK被接收方遲延,則作為回顯值的時(shí)間戳值應(yīng)該對(duì)應(yīng)于最早被確認(rèn)的報(bào)文段。例如,如果兩個(gè)包含11024和10252048字節(jié)的報(bào)文段到達(dá),每一個(gè)都帶有一個(gè)時(shí)間戳選項(xiàng),接收方產(chǎn)生一個(gè)ACK 2049來(lái)對(duì)它們進(jìn)行確認(rèn)。此時(shí),ACK中的時(shí)間戳應(yīng)該是包含字節(jié)1~1024的第1個(gè)報(bào)文段中的時(shí)間戳。這種處理是正確的,因?yàn)榘l(fā)送方在進(jìn)行重傳超時(shí)時(shí)間的計(jì)算時(shí),必須將遲延的ACK也考慮在內(nèi)。

2:如果一個(gè)收到的報(bào)文段雖然在窗口范圍內(nèi)但同時(shí)又是失序,這就表明前面的報(bào)文段已經(jīng)丟失。當(dāng)那個(gè)丟失的報(bào)文段到達(dá)時(shí),它的時(shí)間戳(而不是失序的報(bào)文段的時(shí)間戳)將被回顯。例如,假定有3個(gè)各包含1024字節(jié)數(shù)據(jù)的報(bào)文段,按如下順序接收:包含字節(jié)11024的報(bào)文段1,包含字節(jié)20494072的報(bào)文段3和包含字節(jié)1025~2048的報(bào)文段2。返回的ACK應(yīng)該是帶有報(bào)文段1的時(shí)間戳的ACK 1025(一個(gè)正常的所期望的對(duì)數(shù)據(jù)的ACK)、帶有報(bào)文段1的時(shí)間戳的ACK 1025(一個(gè)重復(fù)的、響應(yīng)位于窗口內(nèi)但卻是失序的報(bào)文段的ACK),然后是帶有報(bào)文段2的時(shí)間戳的ACK 3073(不是報(bào)文段3中的較后的時(shí)間戳)。這與當(dāng)報(bào)文段丟失時(shí)的對(duì)RT T估計(jì)過(guò)高具有同樣的效果,但這比估計(jì)過(guò)低要好些。而且,如果最后的ACK含有來(lái)自報(bào)文段3的時(shí)間戳,它可以包括重復(fù)的ACK返回和報(bào)文段2被重傳所需要的時(shí)間,或者可以包括發(fā)送方的報(bào)文段2的重傳超時(shí)定時(shí)器到期的時(shí)間。無(wú)論在哪一種情況下,回顯報(bào)文段3的時(shí)間戳將引起發(fā)送方的RT T計(jì)算出現(xiàn)偏差。

盡管時(shí)間戳選項(xiàng)能夠更好地計(jì)算RTT,它還為發(fā)送方提供了一種方法,以避免接收到舊的報(bào)文段,并認(rèn)為它們是現(xiàn)在的數(shù)據(jù)的一部分。下一節(jié)將對(duì)此進(jìn)行描述。

24.6 PAWS:防止回繞的序號(hào)

考慮一個(gè)使用窗口擴(kuò)大選項(xiàng)的TCP連接,其最大可能的窗口大小為1千兆字節(jié)(230)(最大的窗口是65535×214,而不是216×214,但只比這個(gè)數(shù)值小一點(diǎn)點(diǎn),并不影響這里的討論)。還假定使用了時(shí)間戳選項(xiàng),并且由發(fā)送方指定的時(shí)間戳對(duì)每個(gè)將要發(fā)送的窗口加1(這是保守的方法。通常時(shí)間戳比這種方式增加得快)。圖24-8顯示了在傳輸6千兆字節(jié)的數(shù)據(jù)時(shí),在兩個(gè)主機(jī)之間可能的數(shù)據(jù)流。為了避免使用許多10位的數(shù)字,我們使用G來(lái)表示1073 741 824的倍數(shù)。我們還使用了tcpdump的記號(hào),即用J:K來(lái)表示通過(guò)了J字節(jié)的數(shù)據(jù),且包括字節(jié)K-1。

圖24-8 在6個(gè)1千兆字節(jié)的窗口中傳輸6千兆字節(jié)的數(shù)據(jù)

32 bit的序號(hào)在時(shí)間D和時(shí)間E之間發(fā)生了回繞。假定一個(gè)報(bào)文段在時(shí)間B丟失并被重傳。還假定這個(gè)丟失的報(bào)文段在時(shí)間E重新出現(xiàn)。

這假定了在報(bào)文段丟失和重新出現(xiàn)之間的時(shí)間差小于MSL,否則這個(gè)報(bào)文段在它的TTL到期時(shí)會(huì)被某個(gè)路由器丟棄。正如我們前面提到的,這種情況只有在高速連接上才會(huì)發(fā)生,此時(shí)舊的報(bào)文段重新出現(xiàn),并帶有當(dāng)前要傳輸?shù)男蛱?hào)。

我們還可以從圖24-8中觀察到使用時(shí)間戳可以避免這種情況。接收方將時(shí)間戳視為序列號(hào)的一個(gè)32 bit的擴(kuò)展。由于在時(shí)間E重新出現(xiàn)的報(bào)文段的時(shí)間戳為2,這比最近有效的時(shí)間戳?。?或6),因此PAWS算法將其丟棄。

PAWS算法不需要在發(fā)送方和接收方之間進(jìn)行任何形式的時(shí)間同步。接收方所需要的就是時(shí)間戳的值應(yīng)該單調(diào)遞增,并且每個(gè)窗口至少增加1。

24.7 T/TCP:為事務(wù)用的TCP擴(kuò)展

TCP提供的是一種虛電路方式的運(yùn)輸服務(wù)。一個(gè)連接的生存時(shí)間包括三個(gè)不同的階段:建立、數(shù)據(jù)傳輸和終止。這種虛電路服務(wù)非常適合諸如遠(yuǎn)程注冊(cè)和文件傳輸之類的應(yīng)用。

但是,還有出現(xiàn)其他的應(yīng)用進(jìn)程被設(shè)計(jì)成使用事務(wù)服務(wù)。一個(gè)事務(wù)(transaction)就是符合下面這些特征的一個(gè)客戶請(qǐng)求及其隨后的服務(wù)器響應(yīng)。

1:應(yīng)該避免連接建立和連接終止的開銷,在可能的時(shí)候,發(fā)送一個(gè)請(qǐng)求分組并接收一個(gè)應(yīng)答分組。

2:等待時(shí)間應(yīng)當(dāng)減少到等于RTT與SPT之和。其中RTT(Round-Trip Time)為往返時(shí)間,而SPT(Server Processing Time)則是服務(wù)器處理請(qǐng)求的時(shí)間。

3:服務(wù)器應(yīng)當(dāng)能夠檢測(cè)出重復(fù)的請(qǐng)求,并且當(dāng)收到一個(gè)重復(fù)的請(qǐng)求時(shí)不重新處理事務(wù)(避免重新處理意味著服務(wù)器不必再次處理請(qǐng)求,而是返回保存的、與該請(qǐng)求對(duì)應(yīng)的應(yīng)答)。

我們已經(jīng)看到的一個(gè)使用這種類型服務(wù)的應(yīng)用就是域名服務(wù)(第14章),盡管DNS與服務(wù)器重新處理重復(fù)的請(qǐng)求無(wú)關(guān)。

如今一個(gè)應(yīng)用程序設(shè)計(jì)人員面對(duì)的一種選擇是使用TCP還是UDP。TCP提供了過(guò)多的事務(wù)特征,而UDP提供的則不夠。通常應(yīng)用程序使用UDP來(lái)構(gòu)造(避免TCP連接的開銷),而許多需要的特征(如動(dòng)態(tài)超時(shí)和重傳、擁塞避免等)被放置在應(yīng)用層,一遍又一遍的重新設(shè)計(jì)和實(shí)現(xiàn)。

一個(gè)較好的解決方法是提供一個(gè)能夠提供足夠多的事務(wù)處理功能的運(yùn)輸層。我們?cè)诒竟?jié)所介紹的事務(wù)協(xié)議被稱為T/TCP。我們從它的定義,即RFC 1379 [Braden 1992b]和[Braden1992c],開始介紹。

大多數(shù)的TCP需要使用7個(gè)報(bào)文段來(lái)打開和關(guān)閉一個(gè)連接(見圖18-13)?,F(xiàn)在增加三個(gè)報(bào)文段:一個(gè)對(duì)應(yīng)于請(qǐng)求,一個(gè)對(duì)應(yīng)于應(yīng)答和對(duì)請(qǐng)求的確認(rèn),第三個(gè)對(duì)應(yīng)于對(duì)應(yīng)答的確認(rèn)。如果額外的控制比特被追加到報(bào)文段上—也就是,第1個(gè)報(bào)文段帶有SYN、客戶請(qǐng)求和一個(gè)FIN—客戶仍然能夠看到一個(gè)2倍的RTT與SPT之和的最小開銷(與數(shù)據(jù)一起發(fā)送一個(gè)SYN和FIN是合法的;當(dāng)前的TCP是否能夠正確處理它們是另外一個(gè)問(wèn)題)。

另一個(gè)與TCP有關(guān)的問(wèn)題是TIME_WAIT狀態(tài)和它需要的2MSL的等待時(shí)間。正如在習(xí)題18.14中看到的,這使兩個(gè)主機(jī)之間的事務(wù)率降低到每秒268個(gè)。

TCP為處理事務(wù)而需要進(jìn)行的兩個(gè)改動(dòng)是避免三次握手和縮短WAIT_TIME狀態(tài)。T/TCP通過(guò)使用加速打開來(lái)避免三次握手:

1:它為打開的連接指定一個(gè)32 bit的連接計(jì)數(shù)CC(Connection Count),無(wú)論主動(dòng)打開還是被動(dòng)打開。一個(gè)主機(jī)的CC值從一個(gè)全局計(jì)數(shù)器中獲得,該計(jì)數(shù)器每次被使用時(shí)加1。

2:在兩個(gè)使用T/TCP的主機(jī)之間的每一個(gè)報(bào)文段都包括一個(gè)新的TCP選項(xiàng)CC。這個(gè)選項(xiàng)的長(zhǎng)度為6個(gè)字節(jié),包含發(fā)送方在該連接上的32 bit的CC值。

3:一個(gè)主機(jī)維持一個(gè)緩存,該緩存保留每個(gè)主機(jī)上一次的CC值,這些值從來(lái)自這個(gè)主機(jī)的一個(gè)可接受的SYN報(bào)文段中獲得。

4:當(dāng)在一個(gè)開始的SYN中收到一個(gè)CC選項(xiàng)的時(shí)候,接收方比較收到的值與為該發(fā)送方緩存的CC值。如果接收到的CC比緩存的大,則該SYN是新的,報(bào)文段中的任何數(shù)據(jù)被傳遞給接收應(yīng)用進(jìn)程(服務(wù)器)。這個(gè)連接被稱為半同步。如果接收的CC比緩存的小,或者接收主機(jī)上沒有對(duì)應(yīng)這個(gè)客戶的緩存CC,則執(zhí)行正常的TCP三次握手過(guò)程。

5:為響應(yīng)一個(gè)開始的SYN,帶有SYN和ACK的報(bào)文段在另一個(gè)被稱為CCECHO的選項(xiàng)中回顯所接收到的CC值。

6:在一個(gè)非SYN報(bào)文段中的CC值檢測(cè)和拒絕來(lái)自同一個(gè)連接的前一個(gè)替身的任何重復(fù)的報(bào)文段。

這種“加速打開”避免了使用三次握手的要求,除非客戶或者服務(wù)器已經(jīng)崩潰并重新啟動(dòng)。這樣做的代價(jià)是服務(wù)器必須記住從每個(gè)客戶接收的最近的CC值。

基于在兩個(gè)主機(jī)之間測(cè)量RTT來(lái)動(dòng)態(tài)計(jì)算TIME_WAIT的延時(shí),可以縮短TIME_WAIT狀態(tài)。TIME_WAIT時(shí)延被設(shè)置為8倍的重傳超時(shí)值RTO(見21.3節(jié))。

通過(guò)使用這些特征,最小的事務(wù)序列是交換三個(gè)報(bào)文段:

1:由一個(gè)主動(dòng)打開引起的客戶到服務(wù)器:客戶的SYN、客戶的數(shù)據(jù)(請(qǐng)求)、客戶的FIN以及客戶的CC。當(dāng)被動(dòng)的服務(wù)器TCP接收到這個(gè)報(bào)文段的時(shí)候,如果客戶的CC比為這個(gè)客戶緩存的CC要大,則客戶的數(shù)據(jù)被傳送給服務(wù)器應(yīng)用程序進(jìn)行處理。

2:服務(wù)器到客戶:服務(wù)器的SYN、服務(wù)器的數(shù)據(jù)(應(yīng)答)、服務(wù)器的FIN、對(duì)客戶的FIN的ACK、服務(wù)器的CC以及客戶的CC的CCECHO。由于TCP的確認(rèn)是累積的,這個(gè)對(duì)客戶的FIN的ACK也對(duì)客戶的SYN、數(shù)據(jù)及FIN進(jìn)行了確認(rèn)。
當(dāng)客戶TCP接收到這個(gè)報(bào)文段,就將其傳送給客戶應(yīng)用進(jìn)程。

3:客戶到服務(wù)器:對(duì)服務(wù)器的FIN的ACK,它也確認(rèn)了服務(wù)器的SYN、數(shù)據(jù)和FIN。客戶對(duì)它的請(qǐng)求的響應(yīng)時(shí)間為RTT與SPT的和。

在參考資料中有許多關(guān)于實(shí)現(xiàn)這個(gè)TCP選項(xiàng)的很好的地方。我們?cè)谶@里將它們歸納如下:

1:服務(wù)器的SYN和ACK(第2個(gè)報(bào)文段)必須被遲延,從而允許應(yīng)答與它一起捎帶發(fā)送(通常對(duì)SYN的ACK是不遲延的)。但它也不能遲延得太多,否則客戶將超時(shí)并引起重傳。

2:請(qǐng)求可以需要多個(gè)報(bào)文段,但是服務(wù)器必須對(duì)它們可能失序達(dá)到的情況進(jìn)行處理(通常當(dāng)數(shù)據(jù)在SYN之前到達(dá)時(shí),該數(shù)據(jù)被丟棄并產(chǎn)生一個(gè)復(fù)位。通過(guò)使用T/TCP,這些失序的數(shù)據(jù)將放入隊(duì)列中處理)。

3:API必須使服務(wù)器進(jìn)程用一個(gè)單一的操作來(lái)發(fā)送數(shù)據(jù)和關(guān)閉連接,從而允許第二個(gè)報(bào)文段中的FIN與應(yīng)答一起捎帶發(fā)送(通常應(yīng)用進(jìn)程先寫應(yīng)答,從而引起發(fā)送一個(gè)數(shù)據(jù)報(bào)文段,然后關(guān)閉連接,引起發(fā)送FIN)。

4:在收到來(lái)自服務(wù)器的MSS通告之前,客戶在第1個(gè)報(bào)文段中正在發(fā)送數(shù)據(jù)。為避免限制客戶的MSS為536,一個(gè)給定主機(jī)的MSS應(yīng)該與它的CC值一起緩存。

5:客戶在沒有接收到來(lái)自服務(wù)器的窗口通告之前也可以向服務(wù)器發(fā)送數(shù)據(jù)。T/TCP建議默認(rèn)的窗口為4096,并且也為服務(wù)器緩存擁塞門限。

6:使用最小3個(gè)報(bào)文段交換,在每個(gè)方向上只能計(jì)算一個(gè)RTT。加上包括了服務(wù)器處理時(shí)間的客戶測(cè)量RT T。這意味著被平滑的RTT及其方差的值也必須為服務(wù)器緩存起來(lái),這與我們?cè)?1.9節(jié)描述的類似。

T/TCP的特征中吸引人的地方在于它對(duì)現(xiàn)有協(xié)議進(jìn)行了最小的修改,同時(shí)又兼容了現(xiàn)有的實(shí)現(xiàn)。它還利用了TCP中現(xiàn)有的工程特征(動(dòng)態(tài)超時(shí)和重傳、擁塞避免等),而不是迫使應(yīng)用進(jìn)程來(lái)處理這些問(wèn)題。

一個(gè)可作為替換的事務(wù)協(xié)議是通用報(bào)文事務(wù)協(xié)議VMTP(Versatile Message Transaction Protocol),該協(xié)議在RFC 1045 [Cheriton 1988]中進(jìn)行了描述。與T/TCP是現(xiàn)有協(xié)議的一個(gè)小的擴(kuò)充不同,VMTP是使用IP的一個(gè)完整的運(yùn)輸層。VMTP處理差錯(cuò)檢測(cè)、重傳和重復(fù)壓縮。它還支持多播通信。

24.8 TCP的性能

在80年代中期出版的數(shù)值顯示出TCP在一個(gè)以太網(wǎng)上的吞吐量在每秒100 000~200 000字節(jié)之間([Stevens 1990]的17.5節(jié)給出了參考文獻(xiàn))。從那時(shí)起事情已經(jīng)發(fā)生了許多改變?,F(xiàn)在通常使用的硬件(工作站和更快的個(gè)人電腦)每秒可以傳輸800 000字節(jié)或者更快。

在10Mb/s的以太網(wǎng)上計(jì)算我們能夠觀察到的理論上的TCP最大吞吐量是一件值得做的練習(xí)[Warnock 1991]。我們可以在圖24-9中看到這個(gè)計(jì)算的基礎(chǔ)。這個(gè)圖顯示了滿長(zhǎng)度的數(shù)據(jù)報(bào)文段和一個(gè)ACK交換的全部的字節(jié)。

圖24-9 計(jì)算以太網(wǎng)理論上最大 吞吐量的字段大小

我們必須計(jì)及所有的開銷:前同步碼、加到確認(rèn)上的填充字節(jié)、循環(huán)冗余檢驗(yàn)CRC以及分組之間的最小間隔(9.6ms,相當(dāng)在10 Mb/s速率下的12個(gè)字節(jié))。

首先假定發(fā)送方傳輸兩個(gè)背對(duì)背、滿長(zhǎng)度的數(shù)據(jù)報(bào)文段,然后接收方為這兩個(gè)報(bào)文段發(fā)送一個(gè)ACK。于是最大的吞吐量(用戶數(shù)據(jù))為:


如果TCP窗口開到它的最大值(65535,不使用窗口擴(kuò)大選項(xiàng)),這就允許一個(gè)窗口容納44個(gè)1460字節(jié)的報(bào)文段。如果接收方每個(gè)報(bào)文段發(fā)送一個(gè)ACK,則計(jì)算變?yōu)椋?/p>

這就是理論上的限制,并做出某些假定:接收方發(fā)送的一個(gè)ACK沒有和發(fā)送方的報(bào)文段之一在以太網(wǎng)上發(fā)生沖突;發(fā)送方可按以太網(wǎng)的最小間隔時(shí)間來(lái)發(fā)送兩個(gè)報(bào)文段;接收方可以在最小的以太網(wǎng)間隔時(shí)間內(nèi)產(chǎn)生一個(gè)ACK。不論在這些數(shù)字上多么樂觀,[Warnock 1991]在一個(gè)以太網(wǎng)上使用標(biāo)準(zhǔn)的多用戶工作站(即使是快的工作站)測(cè)量到了一個(gè)連續(xù)的1075 000字節(jié)/秒的速率,這個(gè)值在理論值的90%之內(nèi)。

當(dāng)移到更快的網(wǎng)絡(luò)上時(shí),如FDDI(100 Mb/s),[Schryver 1993]指出三個(gè)商業(yè)廠家已經(jīng)演示了在FDDI上的TCP在80 Mb/s~90 Mb/s之間。即使在有更多帶寬的環(huán)境下,[Borman 1992]報(bào)告說(shuō)兩個(gè)Gray Y-MP計(jì)算機(jī)在一個(gè)800 Mb/s的HIPPI通道上最大值為781 Mb/s,而運(yùn)行在一個(gè)Gray Y-MP上的使用環(huán)回接口的兩個(gè)進(jìn)程間的速率為907 Mb/s。

下面這些實(shí)際限制適用于任何的實(shí)際情況[Borman 1991]。

1:不能比最慢的鏈路運(yùn)行得更快。

2:不能比最慢的機(jī)器的內(nèi)存運(yùn)行得更快。這假定實(shí)現(xiàn)是只使用一遍數(shù)據(jù)。如果不是這樣(也就是說(shuō),實(shí)現(xiàn)使用一遍數(shù)據(jù)是將它從用戶空間復(fù)制到內(nèi)核中,而使用另一遍數(shù)據(jù)是計(jì)算TCP的檢驗(yàn)和),那么將運(yùn)行得更慢。[Dalton et al.1993]描述了將數(shù)據(jù)復(fù)制數(shù)目減少?gòu)亩挂粋€(gè)標(biāo)準(zhǔn)伯克利源程序的性能得到改進(jìn)。[Partridge and Pink 1993]將類似的“復(fù)制與檢驗(yàn)和”的改變與其他性能改進(jìn)措施一道應(yīng)用于UDP,從而將UDP的性能提高了約30%。

3:不能夠比由接收方提供的窗口大小除以往返時(shí)間所得結(jié)果運(yùn)行得更快(這就是帶寬時(shí)延乘積公式,使用窗口大小作為帶寬時(shí)延乘積,并解出帶寬)。如果使用24.4節(jié)的最大窗口擴(kuò)大因子14,則窗口大小為1.073千兆字節(jié),所以這除以RTT的結(jié)果就是帶寬的極限。

所有這些數(shù)字的重要意義就是TCP的最高運(yùn)行速率的真正上限是由TCP的窗口大小和光速?zèng)Q定的。正如[Partridge and Pink 1993]中計(jì)算的那樣,許多協(xié)議性能問(wèn)題在于實(shí)現(xiàn)中的缺陷而不是協(xié)議所固有的一些限制。

24.9 小結(jié)

本章已經(jīng)討論了五個(gè)新的TCP特征:路徑MTU發(fā)現(xiàn)、窗口擴(kuò)大選項(xiàng)、時(shí)間戳選項(xiàng)、序號(hào)回繞保護(hù)以及使用改進(jìn)的TCP事務(wù)處理。我們觀察到中間的三個(gè)特征是為在長(zhǎng)肥管道——具有大的帶寬時(shí)延乘積的網(wǎng)絡(luò)—上優(yōu)化性能所需要的。

路徑MTU發(fā)現(xiàn)在MTU較大時(shí),對(duì)于非本地連接,允許TCP使用比默認(rèn)的536大的窗口。這樣可以提高性能。

窗口擴(kuò)大選項(xiàng)使最大的TCP窗口從65535增加到1千兆字節(jié)以上。時(shí)間戳選項(xiàng)允許多個(gè)報(bào)文段被精確計(jì)時(shí),并允許接收方提供序號(hào)回繞保護(hù)(PAWS)。這對(duì)于高速連接是必須的。這些新的TCP選項(xiàng)在連接時(shí)進(jìn)行協(xié)商,并被不理解它們的舊系統(tǒng)忽略,從而允許較新的系統(tǒng)與舊的系統(tǒng)進(jìn)行交互。

為事務(wù)用的TCP擴(kuò)展,即T/TCP,允許一個(gè)客戶/服務(wù)器的請(qǐng)求-應(yīng)答序列在通常的情況下只使用三個(gè)報(bào)文段來(lái)完成。它避免使用三次握手,并縮短了TIME_WAIT狀態(tài),其方法是為每個(gè)主機(jī)高速緩存少量的信息,這些信息曾用來(lái)建立過(guò)一個(gè)連接。它還在包含數(shù)據(jù)報(bào)文段中使用SYN和FIN標(biāo)志。

由于還有許多關(guān)于TCP能夠運(yùn)行多快的不精確的傳聞,因此我們以對(duì)TCP性能的分析來(lái)結(jié)束本章。對(duì)于一個(gè)使用本章介紹的較新特征、協(xié)調(diào)得非常好的實(shí)現(xiàn)而言,TCP的性能僅受最大的1千兆字節(jié)窗口和光速(也就是往返時(shí)間)的限制。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 21.1 引言 TCP提供可靠的運(yùn)輸層。它使用的方法之一就是確認(rèn)從另一端收到的數(shù)據(jù)。但數(shù)據(jù)和確認(rèn)都有可能會(huì)丟失。T...
    張芳濤閱讀 3,383評(píng)論 0 8
  • 18.1 引言 TCP是一個(gè)面向連接的協(xié)議。無(wú)論哪一方向另一方發(fā)送數(shù)據(jù)之前,都必須先在雙方之間建立一條連接。本章將...
    張芳濤閱讀 3,536評(píng)論 0 13
  • 個(gè)人認(rèn)為,Goodboy1881先生的TCP /IP 協(xié)議詳解學(xué)習(xí)博客系列博客是一部非常精彩的學(xué)習(xí)筆記,這雖然只是...
    貳零壹柒_fc10閱讀 5,210評(píng)論 0 8
  • 1.這篇文章不是本人原創(chuàng)的,只是個(gè)人為了對(duì)這部分知識(shí)做一個(gè)整理和系統(tǒng)的輸出而編輯成的,在此鄭重地向本文所引用文章的...
    SOMCENT閱讀 13,389評(píng)論 6 174
  • 20.1 引言 在第15章我們看到TFTP使用了停止等待協(xié)議。數(shù)據(jù)發(fā)送方在發(fā)送下一個(gè)數(shù)據(jù)塊之前需要等待接收對(duì)已發(fā)送...
    張芳濤閱讀 941評(píng)論 0 2

友情鏈接更多精彩內(nèi)容