国产18禁黄网站免费观看,99爱在线精品免费观看,粉嫩metart人体欣赏,99久久99精品久久久久久,6080亚洲人久久精品

2015軟件水平測(cè)試:TCP協(xié)議的部分解析(1)

時(shí)間:2015-04-07 13:48:00   來(lái)源:無(wú)憂考網(wǎng)     [字體: ]
1.網(wǎng)絡(luò)協(xié)議設(shè)計(jì)

  ISO提出了OSI分層網(wǎng)絡(luò)模型,這種分層模型是理論上的,TCP/IP最終實(shí)現(xiàn)了一個(gè)分層的協(xié)議模型,每一個(gè)層次對(duì)應(yīng)一組網(wǎng)絡(luò)協(xié)議完成一組特定的功能,該組網(wǎng)絡(luò)協(xié)議被其下的層次復(fù)用和解復(fù)用。這就是分層模型的本質(zhì),最終所有的邏輯被編碼到線纜或者電磁波。

  分層模型是很好理解的,然而對(duì)于每一層的協(xié)議設(shè)計(jì)卻不是那么容易。TCP/IP的漂亮之處在于:協(xié)議越往上層越復(fù)雜。我們把網(wǎng)絡(luò)定義為互相連接在一起的設(shè)備,網(wǎng)絡(luò)的本質(zhì)作用還是“端到端”的通信,然而希望互相通信的設(shè)備并不一定要“直接”連接在一起,因此必然需要一些中間的設(shè)備負(fù)責(zé)轉(zhuǎn)發(fā)數(shù)據(jù),因此就把連接這些中間設(shè)備的線纜上跑的協(xié)議定義為鏈路層協(xié)議,實(shí)際上所謂鏈路其實(shí)就是始發(fā)與一個(gè)設(shè)備,通過(guò)一根線,終止于另一個(gè)設(shè)備。我們把一條鏈路稱為“一跳”。因此一個(gè)端到端的網(wǎng)絡(luò)包含了“很多跳”。

  2.TCP和IP協(xié)議

  終止于IP協(xié)議,我們已經(jīng)可以完成一個(gè)端到端的通信,為何還需要TCP協(xié)議?這是一個(gè)問(wèn)題,理解了這個(gè)問(wèn)題,我們就能理解TCP協(xié)議為何成了現(xiàn)在這個(gè)樣子,為何如此“復(fù)雜”,為何又如此簡(jiǎn)單。

  正如其名字所展示的那樣,TCP的作用是傳輸控制,也就是控制端到端的傳輸,那為何這種控制不在IP協(xié)議中實(shí)現(xiàn)的。答案很簡(jiǎn)單,那就是這會(huì)增加IP協(xié)議的復(fù)雜性,而IP協(xié)議需要的就是簡(jiǎn)單。這是什么原因造成的呢?

  首先我們認(rèn)識(shí)一下為何IP協(xié)議是沙漏的細(xì)腰部分。它的下層是繁多的鏈路層協(xié)議,這些鏈路提供了相互截然不同且相差很遠(yuǎn)的語(yǔ)義,為了互聯(lián)這些異構(gòu)的網(wǎng)絡(luò),我們需要一個(gè)網(wǎng)絡(luò)層協(xié)議起碼要提供一些適配的功能,另外它必然不能提供太多的“保證性服務(wù)”,因?yàn)樯蠈拥谋WC性依賴下層的約束性更強(qiáng)的保證性,你永遠(yuǎn)無(wú)法在一個(gè)100M吞吐量的鏈路之上實(shí)現(xiàn)的IP協(xié)議保證1000M的吞吐量...

  IP協(xié)議設(shè)計(jì)為分組轉(zhuǎn)發(fā)協(xié)議,每一跳都要經(jīng)過(guò)一個(gè)中間節(jié)點(diǎn),路由的設(shè)計(jì)是TCP/IP網(wǎng)絡(luò)的另一大創(chuàng)舉,這樣,IP協(xié)議就無(wú)需方向性,路由信息和協(xié)議本身不再?gòu)?qiáng)關(guān)聯(lián),它們僅僅通過(guò)IP地址來(lái)關(guān)聯(lián),因此,IP協(xié)議更加簡(jiǎn)單。路由器作為中間節(jié)點(diǎn)也不能太復(fù)雜,這涉及到成本問(wèn)題,因此路由器只負(fù)責(zé)選路以及轉(zhuǎn)發(fā)數(shù)據(jù)包。

  因此傳輸控制協(xié)議必然需要在端點(diǎn)實(shí)現(xiàn)。在我們?cè)斦凾CP協(xié)議之前,首先要看一下它不能做什么,由于IP協(xié)議不提供保證,TCP也不能提供依賴于IP下層鏈路的這種保證,比如帶寬,比如時(shí)延,這些都是鏈路層決定的,既然IP協(xié)議無(wú)法修補(bǔ),TCP也不能,然而它卻能修正始于IP層的一些“不可保證性質(zhì)”,這些性質(zhì)包括IP層的不可靠,IP層的不按順序,IP層的無(wú)方向/無(wú)連接。

  將該小節(jié)總結(jié)一下,TCP/IP 模型從下往上,功能增加,需要實(shí)現(xiàn)的設(shè)備減少,然而設(shè)備的復(fù)雜性卻在增加,這樣保證了成本的最小化,至于性能或者因素,靠軟件來(lái)調(diào)節(jié)吧,TCP協(xié)議就是這樣的軟件,實(shí)際上最開(kāi)始的時(shí)候,TCP并不考慮性能,效率,公平性,正是考慮了這些,TCP協(xié)議才復(fù)雜了起來(lái)。

  3.TCP協(xié)議

  這是一個(gè)純軟件協(xié)議,為何將其設(shè)計(jì)上兩個(gè)端點(diǎn),參見(jiàn)上一小節(jié),本節(jié)詳述TCP協(xié)議,中間也穿插一些簡(jiǎn)短的論述。

  3.1.TCP協(xié)議

  確切的說(shuō),TCP協(xié)議有兩重身份,作為網(wǎng)絡(luò)協(xié)議,它彌補(bǔ)了IP協(xié)議盡力而為服務(wù)的不足,實(shí)現(xiàn)了有連接,可靠傳輸,報(bào)文按序到達(dá)。作為一個(gè)主機(jī)軟件,它和 UDP以及左右的傳輸層協(xié)議隔離了主機(jī)服務(wù)和網(wǎng)絡(luò),它們可以被看做是一個(gè)多路復(fù)用/解復(fù)用器,將諸多的主機(jī)進(jìn)程數(shù)據(jù)復(fù)用/解復(fù)用到IP層。可以看出,不管從哪個(gè)角度,TCP都作為一個(gè)接口存在,作為網(wǎng)絡(luò)協(xié)議,它和對(duì)端的TCP接口,實(shí)現(xiàn)TCP的控制邏輯,作為多路復(fù)用/解復(fù)用器,它和下層IP 協(xié)議接口,實(shí)現(xiàn)協(xié)議棧的功能,而這正是分層網(wǎng)絡(luò)協(xié)議模型的基本定義(兩類接口,一類和下層接口,另一類和對(duì)等層接口)。

  我們習(xí)慣于將TCP作為協(xié)議棧的最頂端,而不把應(yīng)用層協(xié)議當(dāng)成協(xié)議棧的一部分,這部分是因?yàn)閼?yīng)用層被TCP/UDP解復(fù)用了之后,呈現(xiàn)出了一種太復(fù)雜的局面,應(yīng)用層協(xié)議用一種不同截然不同的方式被解釋,應(yīng)用層協(xié)議習(xí)慣于用類似ASN.1標(biāo)準(zhǔn)來(lái)封裝,這正體現(xiàn)了TCP協(xié)議作為多路復(fù)用/解復(fù)用器的重要性,由于直接和應(yīng)用接口,它可以很容易直接被應(yīng)用控制,實(shí)現(xiàn)不同的傳輸控制策略,這也是TCP被設(shè)計(jì)到離應(yīng)用不太遠(yuǎn)的地方的原因之一。

  總之,TCP要點(diǎn)有四,一曰有連接,二曰可靠傳輸,三曰數(shù)據(jù)按照到達(dá),四曰端到端流量控制。注意,TCP被設(shè)計(jì)時(shí)只保證這四點(diǎn),此時(shí)它雖然也有些問(wèn)題,然而很簡(jiǎn)單,然而更大的問(wèn)題很快呈現(xiàn)出來(lái),使之不得不考慮和IP網(wǎng)絡(luò)相關(guān)的東西,比如公平性,效率,因此增加了擁塞控制,這樣TCP就成了現(xiàn)在這個(gè)樣子。

  3.2.有連接,可靠傳輸,數(shù)據(jù)按序到達(dá)的TCP

  IP 協(xié)議是沒(méi)有方向的,數(shù)據(jù)報(bào)傳輸能到達(dá)對(duì)端全靠路由,因此它是一跳一跳地到達(dá)對(duì)端的,只要有一跳沒(méi)有到達(dá)對(duì)端的路由,那么數(shù)據(jù)傳輸將失敗,其實(shí)路由也是互聯(lián)網(wǎng)的核心之一,實(shí)際上IP層提供的核心基本功能有兩點(diǎn),第一點(diǎn)是地址管理,第二點(diǎn)就是路由選路。TCP利用了IP路由這個(gè)簡(jiǎn)單的功能,因此TCP不必考慮選路,這又一個(gè)它被設(shè)計(jì)成端到端協(xié)議的原因。

  既然IP已經(jīng)能盡力讓單獨(dú)的數(shù)據(jù)報(bào)到達(dá)對(duì)端,那么TCP就可以在這種盡力而為的網(wǎng)絡(luò)上實(shí)現(xiàn)其它的更加嚴(yán)格的控制功能。TCP給無(wú)連接的IP網(wǎng)絡(luò)通信增加了連接性,確認(rèn)了已經(jīng)發(fā)送出去的數(shù)據(jù)的狀態(tài),并且保證了數(shù)據(jù)的順序。

  3.2.1.有連接

  這是TCP的基本,因?yàn)楹罄m(xù)的傳輸?shù)目煽啃砸约皵?shù)據(jù)順序性都依賴于一條連接,這是最簡(jiǎn)單的實(shí)現(xiàn)方式,因此TCP被設(shè)計(jì)成一種基于流的協(xié)議,既然TCP需要事先建立連接,之后傳輸多少數(shù)據(jù)就無(wú)所謂了,只要是同一連接的數(shù)據(jù)能識(shí)別出來(lái)即可。

  疑難雜癥1:3次握手和4次揮手

  TCP 使用3次握手建立一條連接,該握手初始化了傳輸可靠性以及數(shù)據(jù)順序性必要的信息,這些信息包括兩個(gè)方向的初始序列號(hào),確認(rèn)號(hào)由初始序列號(hào)生成,使用3次握手是因?yàn)?次握手已經(jīng)準(zhǔn)備好了傳輸可靠性以及數(shù)據(jù)順序性所必要的信息,該握手的第3次實(shí)際上并不是需要單獨(dú)傳輸?shù)模耆梢院蛿?shù)據(jù)一起傳輸。

  TCP使用4次揮手拆除一條連接,為何需要4次呢?因?yàn)門CP是一個(gè)全雙工協(xié)議,必須單獨(dú)拆除每一條信道。注意,4次揮手和3次握手的意義是不同的,很多人都會(huì)問(wèn)為何建立連接是3次握手,而拆除連接是4次揮手。3次握手的目的很簡(jiǎn)單,就是分配資源,初始化序列號(hào),這時(shí)還不涉及數(shù)據(jù)傳輸,3次就足夠做到這個(gè)了,而 4次揮手的目的是終止數(shù)據(jù)傳輸,并回收資源,此時(shí)兩個(gè)端點(diǎn)兩個(gè)方向的序列號(hào)已經(jīng)沒(méi)有了任何關(guān)系,必須等待兩方向都沒(méi)有數(shù)據(jù)傳輸時(shí)才能拆除虛鏈路,不像初始化時(shí)那么簡(jiǎn)單,發(fā)現(xiàn)SYN標(biāo)志就初始化一個(gè)序列號(hào)并確認(rèn)SYN的序列號(hào)。因此必須單獨(dú)分別在一個(gè)方向上終止該方向的數(shù)據(jù)傳輸。

  疑難雜癥2:TIME_WAIT狀態(tài)

  為何要有這個(gè)狀態(tài),原因很簡(jiǎn)單,那就是每次建立連接的時(shí)候序列號(hào)都是隨機(jī)產(chǎn)生的,并且這個(gè)序列號(hào)是32位的,會(huì)回繞,F(xiàn)在我來(lái)解釋這和TIME_WAIT有什么關(guān)系。

  任何的TCP分段都要在盡力而為的IP網(wǎng)絡(luò)上傳輸,中間的路由器可能會(huì)隨意的緩存任何的IP數(shù)據(jù)報(bào),它并不管這個(gè)IP數(shù)據(jù)報(bào)上被承載的是什么數(shù)據(jù),然而根據(jù)經(jīng)驗(yàn)和互聯(lián)網(wǎng)的大小,一個(gè)IP數(shù)據(jù)報(bào)最多存活MSL(這是根據(jù)地球表面積,電磁波在各種介質(zhì)中的傳輸速率以及IP協(xié)議的TTL等綜合推算出來(lái)的,如果在火星上,這個(gè)MSL會(huì)大得多...)。

  現(xiàn)在我們考慮終止連接時(shí)的被動(dòng)方發(fā)送了一個(gè)FIN,然后主動(dòng)方回復(fù)了一個(gè)ACK,然而這個(gè)ACK可能會(huì)丟失,這會(huì)造成被動(dòng)方重發(fā)FIN,這個(gè)FIN可能會(huì)在互聯(lián)網(wǎng)上存活MSL。

  如果沒(méi)有TIME_WAIT的話,假設(shè)連接1已經(jīng)斷開(kāi),然而其被動(dòng)方最后重發(fā)的那個(gè)FIN(或者FIN之前發(fā)送的任何TCP分段)還在網(wǎng)絡(luò)上,然而連接2 重用了連接1的所有的5元素(源IP,目的IP,TCP,源端口,目的端口),剛剛將建立好連接,連接1遲到的FIN到達(dá)了,這個(gè)FIN將以比較低但是確實(shí)可能的概率終止掉連接2.

  為何說(shuō)是概率比較低呢?這涉及到一個(gè)匹配問(wèn)題,遲到的FIN分段的序列號(hào)必須落在連接2的一方的期望序列號(hào)范圍之內(nèi)。雖然這種巧合很少發(fā)生,但確實(shí)會(huì)發(fā)生,畢竟初始序列號(hào)是隨機(jī)產(chǎn)生了。因此終止連接的主動(dòng)方必須在接受了被動(dòng)方且回復(fù)了ACK之后等待2*MSL時(shí)間才能進(jìn)入CLOSE狀態(tài),之所以乘以2是因?yàn)檫@是保守的算法,最壞情況下,針對(duì)被動(dòng)方的ACK在以最長(zhǎng)路線(經(jīng)歷一個(gè)MSL)經(jīng)過(guò)互聯(lián)網(wǎng)馬上到達(dá)被動(dòng)方時(shí)丟失。

  為了應(yīng)對(duì)這個(gè)問(wèn)題,RFC793對(duì)初始序列號(hào)的生成有個(gè)建議,那就是設(shè)定一個(gè)基準(zhǔn),在這個(gè)基準(zhǔn)之上搞隨機(jī),這個(gè)基準(zhǔn)就是時(shí)間,我們知道時(shí)間是單調(diào)遞增的。然而這仍然有問(wèn)題,那就是回繞問(wèn)題,如果發(fā)生回繞,那么新的序列號(hào)將會(huì)落到一個(gè)很低的值。因此的辦法就是避開(kāi)“重疊”,其含義就是基準(zhǔn)之上的隨機(jī)要設(shè)定一個(gè)范圍。

  要知道,很多人很不喜歡看到服務(wù)器上出現(xiàn)大量的TIME_WAIT狀態(tài)的連接,因此他們將TIME_WAIT的值設(shè)置的很低,這雖然在大多數(shù)情況下可行,然而確實(shí)也是一種冒險(xiǎn)行為。的方式就是,不要重用一個(gè)連接。

  疑難雜癥3:重用一個(gè)連接和重用一個(gè)套接字

  這是根本不同的,單獨(dú)重用一個(gè)套接字一般不會(huì)有任何問(wèn)題,因?yàn)門CP是基于連接的。比如在服務(wù)器端出現(xiàn)了一個(gè)TIME_WAIT連接,那么該連接標(biāo)識(shí)了一個(gè)五元素,只要客戶端不使用相同的源端口,連接服務(wù)器是沒(méi)有問(wèn)題的,因?yàn)檫t到的FIN永遠(yuǎn)不會(huì)到達(dá)這個(gè)連接。記住,一個(gè)五元素標(biāo)識(shí)了一個(gè)連接,而不是一個(gè)套接字(當(dāng)然,對(duì)于BSD套接字而言,服務(wù)端的accept套接字確實(shí)標(biāo)識(shí)了一個(gè)連接)。

  3.2.2.傳輸可靠性

  基本上傳輸可靠性是靠確認(rèn)號(hào)實(shí)現(xiàn)的,也就是說(shuō),每發(fā)送一個(gè)分段,接下來(lái)接收端必然要發(fā)送一個(gè)確認(rèn),發(fā)送端收到確認(rèn)后才可以發(fā)送下一個(gè)字節(jié)。這個(gè)原則最簡(jiǎn)單不過(guò)了,教科書(shū)上的“停止-等待”協(xié)議就是這個(gè)原則的字節(jié)版本,只是TCP使用了滑動(dòng)窗口機(jī)制使得每次不一定發(fā)送一個(gè)字節(jié),但是這是后話,本節(jié)僅僅談一下確認(rèn)的超時(shí)機(jī)制。

  怎么知道數(shù)據(jù)到達(dá)對(duì)端呢?那就是對(duì)端發(fā)送一個(gè)確認(rèn),但是如果一直收不到對(duì)端的確認(rèn),發(fā)送端等多久呢?如果一直等下去,那么將無(wú)法發(fā)現(xiàn)數(shù)據(jù)的丟失,協(xié)議將不可用,如果等待時(shí)間過(guò)短,可能確認(rèn)還在路上,因此等待時(shí)間是個(gè)問(wèn)題,另外如何去管理這個(gè)超時(shí)時(shí)間也是一個(gè)問(wèn)題。

  疑難雜癥4:超時(shí)時(shí)間的計(jì)算

  絕對(duì)不能隨意去揣測(cè)超時(shí)的時(shí)間,而應(yīng)該給出一個(gè)精確的算法去計(jì)算。毫無(wú)疑問(wèn),一個(gè)TCP分段的回復(fù)到達(dá)的時(shí)間就是一個(gè)數(shù)據(jù)報(bào)往返的時(shí)間,因此標(biāo)準(zhǔn)定義了一個(gè)新的名詞RTT,代表一個(gè)TCP分段的往返時(shí)間。然而我們知道,IP網(wǎng)絡(luò)是盡力而為的,并且路由是動(dòng)態(tài)的,且路由器會(huì)毫無(wú)先兆的緩存或者丟棄任何的數(shù)據(jù)報(bào),因此這個(gè)RTT是需要?jiǎng)討B(tài)測(cè)量的,也就是說(shuō)起碼每隔一段時(shí)間就要測(cè)量一次,如果每次都一樣,萬(wàn)事大吉,然而世界并非如你所愿,因此我們需要找到的恰恰的一個(gè)“平均值”,而不是一個(gè)準(zhǔn)確值。

  這個(gè)平均值如果僅僅直接通過(guò)計(jì)算多次測(cè)量值取算術(shù)平均,那是不恰當(dāng)?shù),因(yàn)閷?duì)于數(shù)據(jù)傳輸延時(shí),我們必須考慮的路徑延遲的瞬間抖動(dòng),否則如果兩次測(cè)量值分別為2和98,那么超時(shí)值將是50,這個(gè)值對(duì)于2而言,太大了,結(jié)果造成了數(shù)據(jù)的延遲過(guò)大(本該重傳的等待了好久才重傳),然而對(duì)于98而言,太小了,結(jié)果造成了過(guò)度重傳(路途遙遠(yuǎn),本該很慢,結(jié)果大量重傳已經(jīng)正確確認(rèn)但是遲到的TCP分段)。

  因此,除了考慮每?jī)纱螠y(cè)量值的偏差之外,其變化率也應(yīng)該考慮在內(nèi),如果變化率過(guò)大,則通過(guò)以變化率為自變量的函數(shù)為主計(jì)算RTT(如果陡然增大,則取值為比較大的正數(shù),如果陡然減小,則取值為比較小的負(fù)數(shù),然后和平均值加權(quán)求和),反之如果變化率很小,則取測(cè)量平均值。這是不言而喻的,這個(gè)算法至今仍然工作的很好。

  疑難雜癥5:超時(shí)計(jì)時(shí)器的管理-每連接單一計(jì)時(shí)器

  很顯然,對(duì)每一個(gè)TCP分段都生成一個(gè)計(jì)時(shí)器是最直接的方式,每個(gè)計(jì)時(shí)器在RTT時(shí)間后到期,如果沒(méi)有收到確認(rèn),則重傳。然而這只是理論上的合理,對(duì)于大多數(shù)操作系統(tǒng)而言,這將帶來(lái)巨大的內(nèi)存開(kāi)銷和調(diào)度開(kāi)銷,因此采取每一個(gè)TCP連接單一計(jì)時(shí)器的設(shè)計(jì)則成了一個(gè)默認(rèn)的選擇?墒菃我坏挠(jì)時(shí)器怎么管理如此多的發(fā)出去的TCP分段呢?又該如何來(lái)設(shè)計(jì)單一的計(jì)時(shí)器呢。

  設(shè)計(jì)單一計(jì)時(shí)器有兩個(gè)原則:1.每一個(gè)報(bào)文在長(zhǎng)期收不到確認(rèn)都必須可以超時(shí);2.這個(gè)長(zhǎng)期收不到中長(zhǎng)期不能和測(cè)量的RTT相隔太遠(yuǎn)。因此RFC2988定義一套很簡(jiǎn)單的原則:

  a.發(fā)送TCP分段時(shí),如果還沒(méi)有重傳定時(shí)器開(kāi)啟,那么開(kāi)啟它。

  b.發(fā)送TCP分段時(shí),如果已經(jīng)有重傳定時(shí)器開(kāi)啟,不再開(kāi)啟它。

  c.收到一個(gè)非冗余ACK時(shí),如果有數(shù)據(jù)在傳輸中,重新開(kāi)啟重傳定時(shí)器。

  d.收到一個(gè)非冗余ACK時(shí),如果沒(méi)有數(shù)據(jù)在傳輸中,則關(guān)閉重傳定時(shí)器。

  我們看看這4條規(guī)則是如何做到以上兩點(diǎn)的,根據(jù)a和c(在c中,注意到ACK是非冗余的),任何TCP分段只要不被確認(rèn),超時(shí)定時(shí)器總會(huì)超時(shí)的。然而為何需要c呢?只有規(guī)則a存在的話,也可以做到原則1。實(shí)際上確實(shí)是這樣的,但是為了不會(huì)出現(xiàn)過(guò)早重傳,才添加了規(guī)則c,如果沒(méi)有規(guī)則c,那么萬(wàn)一在重傳定時(shí)器到期前,發(fā)送了一些數(shù)據(jù),這樣在定時(shí)器到期后,除了很早發(fā)送的數(shù)據(jù)能收到ACK外,其它稍晚些發(fā)送的數(shù)據(jù)的ACK都將不會(huì)到來(lái),因此這些數(shù)據(jù)都將被重傳。有了規(guī)則c之后,只要有分段ACK到來(lái),則重置重傳定時(shí)器,這很合理,因此大多數(shù)正常情況下,從數(shù)據(jù)的發(fā)出到ACK的到來(lái)這段時(shí)間以及計(jì)算得到的RTT以及重傳定時(shí)器超時(shí)的時(shí)間這三者相差并不大,一個(gè)ACK到來(lái)后重置定時(shí)器可以保護(hù)后發(fā)的數(shù)據(jù)不被過(guò)早重傳。

  這里面還有一些細(xì)節(jié)需要說(shuō)明。一個(gè)ACK到來(lái)了,說(shuō)明后續(xù)的ACK很可能會(huì)依次到來(lái),也就是說(shuō)丟失的可能性并不大,另外,即使真的有后發(fā)的TCP分段丟失現(xiàn)象發(fā)生,也會(huì)在最多2倍定時(shí)器超時(shí)時(shí)間的范圍內(nèi)被重傳(假設(shè)該報(bào)文是第一個(gè)報(bào)文發(fā)出啟動(dòng)定時(shí)器之后馬上發(fā)出的,丟失了,第一個(gè)報(bào)文的ACK到來(lái)后又重啟了定時(shí)器,又經(jīng)過(guò)了一個(gè)超時(shí)時(shí)間才會(huì)被重傳)。雖然這里還沒(méi)有涉及擁塞控制,但是可見(jiàn)網(wǎng)絡(luò)擁塞會(huì)引起丟包,丟包會(huì)引起重傳,過(guò)度重傳反過(guò)來(lái)加重網(wǎng)絡(luò)擁塞,設(shè)置規(guī)則c的結(jié)果可以緩解過(guò)多的重傳,畢竟將啟動(dòng)定時(shí)器之后發(fā)送的數(shù)據(jù)的重傳超時(shí)時(shí)間拉長(zhǎng)了最多一倍左右。最多一倍左右的超時(shí)偏差做到了原則2,即“這個(gè)長(zhǎng)期收不到中長(zhǎng)期不能和測(cè)量的RTT相隔太遠(yuǎn)”。

  還有一點(diǎn),如果是一個(gè)發(fā)送序列的最后一個(gè)分段丟失了,后面就不會(huì)收到冗余ACK,這樣就只能等到超時(shí)了,并且超時(shí)時(shí)間幾乎是肯定會(huì)比定時(shí)器超時(shí)時(shí)間更長(zhǎng)。如果這個(gè)分段是在發(fā)送序列的靠后的時(shí)間發(fā)送的且和前面的發(fā)送時(shí)間相隔時(shí)間較遠(yuǎn),則其超時(shí)時(shí)間不會(huì)很大,反之就會(huì)比較大。

  疑難雜癥6:何時(shí)測(cè)量RTT

  目前很多TCP實(shí)現(xiàn)了時(shí)間戳,這樣就方便多了,發(fā)送端再也不需要保存發(fā)送分段的時(shí)間了,只需要將其放入?yún)f(xié)議頭的時(shí)間戳字段,然后接收端將其回顯在ACK即可,然后發(fā)送端收到ACK后,取出時(shí)間戳,和當(dāng)前時(shí)間做算術(shù)差,即可完成一次RTT的測(cè)量。

  3.2.3.數(shù)據(jù)順序性

  基本上傳輸可靠性是靠序列號(hào)實(shí)現(xiàn)的。

  疑難雜癥7:確認(rèn)號(hào)和超時(shí)重傳

  確認(rèn)號(hào)是一個(gè)很詭異的東西,因?yàn)門CP的發(fā)送端對(duì)于發(fā)送出去的一個(gè)數(shù)據(jù)序列,它只要收到一個(gè)確認(rèn)號(hào)就認(rèn)為確認(rèn)號(hào)前面的數(shù)據(jù)都被收到了,即使前面的某個(gè)確認(rèn)號(hào)丟失了,也就是說(shuō),發(fā)送端只認(rèn)最后一個(gè)確認(rèn)號(hào)。這是合理的,因?yàn)榇_認(rèn)號(hào)是接收端發(fā)出的,接收端只確認(rèn)按序到達(dá)的最后一個(gè)TCP分段。

  另外,發(fā)送端重發(fā)了一個(gè)TCP報(bào)文并且接收到該TCP分段的確認(rèn)號(hào),并不能說(shuō)明這個(gè)重發(fā)的報(bào)文被接收了,也可能是數(shù)據(jù)早就被接收了,只是由于其ACK丟失或者其ACK延遲到達(dá)導(dǎo)致了超時(shí)。值得說(shuō)明的是,接收端會(huì)丟棄任何重復(fù)的數(shù)據(jù),即使丟棄了重復(fù)的數(shù)據(jù),其ACK還是會(huì)照發(fā)不誤的。

  標(biāo)準(zhǔn)的早期TCP實(shí)現(xiàn)為,只要一個(gè)TCP分段丟失,即使后面的TCP分段都被完整收到,發(fā)送端還是會(huì)重傳從丟失分段開(kāi)始的所有報(bào)文,這就會(huì)導(dǎo)致一個(gè)問(wèn)題,那就是重傳風(fēng)暴,一個(gè)分段丟失,引起大量的重傳。這種風(fēng)暴實(shí)則不必要的,因?yàn)榇蠖鄶?shù)的TCP實(shí)現(xiàn)中,接收端已經(jīng)緩存了亂序的分段,這些被重傳的丟失分段之后的分段到達(dá)接收端之后,很大的可能性是被丟棄。關(guān)于這一點(diǎn)在擁塞控制被引入之后還會(huì)提及(問(wèn)題先述為快:本來(lái)報(bào)文丟失導(dǎo)致超時(shí)就說(shuō)明網(wǎng)絡(luò)很可能已然擁塞,重傳風(fēng)暴只能加重其擁塞程度)。

  疑難雜癥8:亂序數(shù)據(jù)緩存以及選擇確認(rèn)

  TCP 是保證數(shù)據(jù)順序的,但是并不意味著它總是會(huì)丟棄亂序的TCP分段,具體會(huì)不會(huì)丟棄是和具體實(shí)現(xiàn)相關(guān)的,RFC建議如果內(nèi)存允許,還是要緩存這些亂序到來(lái)的分段,然后實(shí)現(xiàn)一種機(jī)制等到可以拼接成一個(gè)按序序列的時(shí)候?qū)⒕彺娴姆侄纹唇,這就類似于IP協(xié)議中的分片一樣,但是由于IP數(shù)據(jù)報(bào)是不確認(rèn)的,因此IP協(xié)議的實(shí)現(xiàn)必須緩存收到的任何分片而不能將其丟棄,因?yàn)閬G棄了一個(gè)IP分片,它就再也不會(huì)到來(lái)了。

  現(xiàn)在,TCP實(shí)現(xiàn)了一種稱為選擇確認(rèn)的方式,接收端會(huì)顯式告訴發(fā)送端需要重傳哪些分段而不需要重傳哪些分段。這無(wú)疑避免了重傳風(fēng)暴。

  疑難雜癥9:TCP序列號(hào)的回繞的問(wèn)題

  TCP 的序列號(hào)回繞會(huì)引起很多的問(wèn)題,比如序列號(hào)為s的分段發(fā)出之后,m秒后,序列號(hào)比s小的序列號(hào)為j的分段發(fā)出,只不過(guò)此時(shí)的j比上一個(gè)s多了一圈,這就是回繞問(wèn)題,那么如果這后一個(gè)分段到達(dá)接收端,這就會(huì)引發(fā)徹底亂序-本來(lái)j該在s后面,結(jié)果反而到達(dá)前面了,這種亂序是TCP協(xié)議檢查不出來(lái)的。我們仔細(xì)想一下,這種情況確實(shí)會(huì)發(fā)生,數(shù)據(jù)分段并不是一個(gè)字節(jié)一個(gè)字節(jié)發(fā)送出去的,如果存在一個(gè)速率為1Gbps的網(wǎng)絡(luò),TCP發(fā)送端1秒會(huì)發(fā)送125MB的數(shù)據(jù),32位的序列號(hào)空間能傳輸2的32次方個(gè)字節(jié),也就是說(shuō)32秒左右就會(huì)發(fā)生回繞,我們知道這個(gè)值遠(yuǎn)小于MSL值,因此會(huì)發(fā)生的。

  有個(gè)細(xì)節(jié)可能會(huì)引起誤會(huì),那就是TCP的窗口大小空間是序列號(hào)空間的一半,這樣恰好在滿載情況下,數(shù)據(jù)能填滿發(fā)送窗口和接收窗口,序列號(hào)空間正好夠用。然而事實(shí)上,TCP的初始序列號(hào)并不是從0開(kāi)始的,而是隨機(jī)產(chǎn)生的(當(dāng)然要輔助一些更精妙的算法),因此如果初始序列號(hào)比較接近2的32次方,那么很快就會(huì)回繞。

  當(dāng)然,如今可以用時(shí)間戳選項(xiàng)來(lái)輔助作為序列號(hào)的一個(gè)識(shí)別的部分,接收端遇到回繞的情況,需要比較時(shí)間戳,我們知道,時(shí)間戳是單調(diào)遞增的,雖然也會(huì)回繞,然而回繞時(shí)間卻要長(zhǎng)很多。這只是一種策略,在此不詳談。還有一個(gè)很現(xiàn)實(shí)的問(wèn)題,理論上序列號(hào)會(huì)回繞,但是實(shí)際上,有多少TCP的端點(diǎn)主機(jī)直接架設(shè)在1G的網(wǎng)絡(luò)線纜兩端并且接收方和發(fā)送方的窗口還能恰好被同時(shí)填滿。另外,就算發(fā)生了回繞,也不是一件特別的事情,回繞在計(jì)算機(jī)里面太常見(jiàn)了,只需要能識(shí)別出來(lái)即可解決,對(duì)于TCP的序列號(hào)而言,在高速網(wǎng)絡(luò)(點(diǎn)對(duì)點(diǎn)網(wǎng)絡(luò)或者以太網(wǎng))的兩端,數(shù)據(jù)發(fā)生亂序的可能性很小,因此當(dāng)收到一個(gè)序列號(hào)突然變?yōu)?或者終止序列號(hào)小于起始序列號(hào)的情況后,很容易辨別出來(lái),只需要和前一個(gè)確認(rèn)的分段比較即可,如果在一個(gè)經(jīng)過(guò)路由器的網(wǎng)絡(luò)兩端,會(huì)引發(fā)IP數(shù)據(jù)報(bào)的順序重排,對(duì)于TCP而言,雖然還會(huì)發(fā)生回繞,也會(huì)慢得多,且考慮到擁塞窗口(目前還沒(méi)有引入)一般不會(huì)太大,窗口也很難被填滿到65536。

  3.2.4.端到端的流量控制

  端到端的流量控制使用滑動(dòng)窗口來(lái)實(shí)現(xiàn);瑒(dòng)窗口的原理非常簡(jiǎn)單,基本就是一個(gè)生產(chǎn)者/消費(fèi)者模型

  疑難雜癥10:流量控制的真實(shí)意義

  很多人以為流量控制會(huì)很有效的協(xié)調(diào)兩端的流量匹配,確實(shí)是這樣,但是如果你考慮到網(wǎng)絡(luò)的利用率問(wèn)題,TCP的流量控制機(jī)制就不那么完美了,造成這種局面的原因在于,滑動(dòng)窗口只是限制了發(fā)送的數(shù)據(jù),卻沒(méi)有限制最小發(fā)送的數(shù)據(jù),結(jié)果導(dǎo)致一些很小的數(shù)據(jù)被封裝成TCP分段,報(bào)文協(xié)議頭所占的比例過(guò)于大,造成網(wǎng)絡(luò)利用率下降,這就引出了接下來(lái)的內(nèi)容,那就是端到端意義的TCP協(xié)議效率。


終于到了闡述問(wèn)題的時(shí)候了,以上的TCP協(xié)議實(shí)現(xiàn)的非常簡(jiǎn)單,這也是TCP的標(biāo)準(zhǔn)實(shí)現(xiàn),然而很快我們就會(huì)發(fā)現(xiàn)各種各樣的問(wèn)題。這些問(wèn)題導(dǎo)致了標(biāo)準(zhǔn)化協(xié)會(huì)對(duì) TCP協(xié)議進(jìn)行了大量的修補(bǔ),這些修補(bǔ)雜糅在一起讓人們有些云里霧里,不知所措。本文檔就旨在分離這些雜亂的情況,實(shí)際上,根據(jù)RFC,這些雜亂的情況都是可以找到其單獨(dú)的發(fā)展軌跡的。