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

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

時(shí)間:2015-04-07 13:50:00   來(lái)源:無(wú)憂考網(wǎng)     [字體: ]
端到端意義上的TCP協(xié)議效率

  1.三個(gè)問(wèn)題以及解決

  問(wèn)題1描述:接收端處理慢,導(dǎo)致接收窗口被填滿

  這明顯是速率不匹配引發(fā)的問(wèn)題,然而即使速率不匹配,只要滑動(dòng)窗口能協(xié)調(diào)好它們的速率就好,要快都快,要慢都慢,事實(shí)上滑動(dòng)窗口在這一點(diǎn)上做的很好。但是如果我們不得不從效率上來(lái)考慮問(wèn)題的話,事實(shí)就不那么樂(lè)觀了。考慮此時(shí)接收窗口已然被填滿,慢速的應(yīng)用程序慢騰騰的讀取了一個(gè)字節(jié),空出一個(gè)位置,然后通告給TCP的發(fā)送端,發(fā)送端得知空出一個(gè)位置,馬上發(fā)出一個(gè)字節(jié),又將接收端填滿,然后接收應(yīng)用程序又一次慢騰騰...這就是糊涂窗口綜合癥,一個(gè)大多數(shù)人都很熟悉的詞。這個(gè)問(wèn)題極大的浪費(fèi)了網(wǎng)絡(luò)帶寬,降低了網(wǎng)絡(luò)利用率。好比從大同拉100噸煤到北京需要一輛車,拉1Kg煤到北京也需要一輛車(超級(jí)夸張的一個(gè)例子,請(qǐng)不要相信),但是一輛車開(kāi)到北京的開(kāi)銷是一定的...

  問(wèn)題1解決:窗口通告

  對(duì)于問(wèn)題1,很顯然問(wèn)題出在接收端,我們沒(méi)有辦法限制發(fā)送端不發(fā)送小分段,但是卻可以限制接收端通告小窗口,這是合理的,這并不影響應(yīng)用程序,此時(shí)經(jīng)典的延遲/吞吐量反比律將不再適用,因?yàn)榻邮沾翱谑菨M的,其空出一半空間表示還有一半空間有數(shù)據(jù)沒(méi)有被應(yīng)用讀取,和其空出一個(gè)字節(jié)的空間的效果是一樣的,因此可以限制接收端當(dāng)窗口為0時(shí),直接通告給發(fā)送端以阻止其繼續(xù)發(fā)送數(shù)據(jù),只有當(dāng)其接收窗口再次達(dá)到MSS的一半大小的時(shí)候才通告一個(gè)不為0的窗口,此前對(duì)于所有的發(fā)送端的窗口probe分段(用于探測(cè)接收端窗口大小的probe分段,由TCP標(biāo)準(zhǔn)規(guī)定),全部通告窗口為0,這樣發(fā)送端在收到窗口不為0的通告,那么肯定是一個(gè)比較大的窗口,因此發(fā)送端可以一次性發(fā)出一個(gè)很大的TCP分段,包含大量數(shù)據(jù),也即拉了好幾十噸的煤到北京,而不是只拉了幾公斤。

  即,限制窗口通告時(shí)機(jī),解決糊涂窗口綜合癥

  問(wèn)題2描述:發(fā)送端持續(xù)發(fā)送小包,導(dǎo)致窗口閑置

  這明顯是發(fā)送端引起的問(wèn)題,此時(shí)接收端的窗口開(kāi)得很大,然而發(fā)送端卻不積累數(shù)據(jù),還是一味的發(fā)送小塊數(shù)據(jù)分段。只要發(fā)送了任和的分段,接收端都要無(wú)條件接收并且確認(rèn),這完全符合TCP規(guī)范,因此必然要限制發(fā)送端不發(fā)送這樣的小分段。

  問(wèn)題2解決:Nagle算法

  Nagel算法很簡(jiǎn)單,標(biāo)準(zhǔn)的Nagle算法為:

  IF 數(shù)據(jù)的大小和窗口的大小都超過(guò)了MSS

  Then 發(fā)送數(shù)據(jù)分段

  ELSE

  IF 還有發(fā)出的TCP分段的確認(rèn)沒(méi)有到來(lái)

  Then 積累數(shù)據(jù)到發(fā)送隊(duì)列的末尾的TCP分段

  ELSE

  發(fā)送數(shù)據(jù)分段

  EndIF

  EndIF

  可是后來(lái),這個(gè)算法變了,變得更加靈活了,其中的:

  IF 還有發(fā)出的TCP分段的確認(rèn)沒(méi)有到來(lái)

  變成了

  IF 還有發(fā)出的不足MSS大小的TCP分段的確認(rèn)沒(méi)有到來(lái)

  這樣如果發(fā)出了一個(gè)MSS大小的分段還沒(méi)有被確認(rèn),后面也是可以隨時(shí)發(fā)送一個(gè)小分段的,這個(gè)改進(jìn)降低了算法對(duì)延遲時(shí)間的影響。這個(gè)算法體現(xiàn)了一種自適應(yīng)的策略,越是確認(rèn)的快,越是發(fā)送的快,雖然Nagle算法看起來(lái)在積累數(shù)據(jù)增加吞吐量的同時(shí)也加大的時(shí)延,可事實(shí)上,如果對(duì)于類似交互式的應(yīng)用,時(shí)延并不會(huì)增加,因?yàn)檫@類應(yīng)用回復(fù)數(shù)據(jù)也是很快的,比如Telnet之類的服務(wù)必然需要回顯字符,因此能和對(duì)端進(jìn)行自適應(yīng)協(xié)調(diào)。

  注意,Nagle算法是默認(rèn)開(kāi)啟的,但是卻可以關(guān)閉。如果在開(kāi)啟的情況下,那么它就嚴(yán)格按照上述的算法來(lái)執(zhí)行。

  問(wèn)題3.確認(rèn)號(hào)(ACK)本身就是不含數(shù)據(jù)的分段,因此大量的確認(rèn)號(hào)消耗了大量的帶寬

  這是TCP為了確?煽啃詡鬏?shù)囊?guī)范,然而大多數(shù)情況下,ACK還是可以和數(shù)據(jù)一起捎帶傳輸?shù)。如果沒(méi)有捎帶傳輸,那么就只能單獨(dú)回來(lái)一個(gè)ACK,如果這樣的分段太多,網(wǎng)絡(luò)的利用率就會(huì)下降。從大同用火車?yán)奖本?00噸煤,為了確認(rèn)煤已收到,北京需要派一輛同樣的火車空載開(kāi)到大同去復(fù)命,因?yàn)闆](méi)有別的交通工具,只有火車。如果這位復(fù)命者剛開(kāi)著一列火車走,又從大同來(lái)了一車煤,這拉煤的哥們兒又要開(kāi)一列空車去復(fù)命了。

  問(wèn)題3的解決:

  RFC 建議了一種延遲的ACK,也就是說(shuō),ACK在收到數(shù)據(jù)后并不馬上回復(fù),而是延遲一段可以接受的時(shí)間,延遲一段時(shí)間的目的是看能不能和接收方要發(fā)給發(fā)送方的數(shù)據(jù)一起回去,因?yàn)門CP協(xié)議頭中總是包含確認(rèn)號(hào)的,如果能的話,就將ACK一起捎帶回去,這樣網(wǎng)絡(luò)利用率就提高了。往大同復(fù)命的確認(rèn)者不必開(kāi)一輛空載火車回大同了,此時(shí)北京正好有一批貨物要送往大同,這位復(fù)命者搭著這批貨的火車返回大同。

  如果等了一段可以接受的時(shí)間,還是沒(méi)有數(shù)據(jù)要發(fā)往發(fā)送端,此時(shí)就需要單獨(dú)發(fā)送一個(gè)ACK了,然而即使如此,這個(gè)延遲的ACK雖然沒(méi)有等到可以被捎帶的數(shù)據(jù)分段,也可能等到了后續(xù)到來(lái)的TCP分段,這樣它們就可以取者一起返回了,要知道,TCP的確認(rèn)號(hào)是收到的按序報(bào)文的最后一個(gè)字節(jié)的后一個(gè)字節(jié)。最后,RFC建議,延遲的ACK最多等待兩個(gè)分段的積累確認(rèn)。

  2.分析三個(gè)問(wèn)題之間的關(guān)聯(lián)

  三個(gè)問(wèn)題導(dǎo)致的結(jié)果是相同的,但是要知道它們的原因本質(zhì)上是不同的,問(wèn)題1幾乎總是出現(xiàn)在接收端窗口滿的情況下,而問(wèn)題2幾乎總是發(fā)生在窗口閑置的情況下,問(wèn)題3看起來(lái)是最無(wú)聊的,然而由于TCP的要求,必須要有確認(rèn)號(hào),而且一個(gè)確認(rèn)號(hào)就需要一個(gè)TCP分段,這個(gè)分段不含數(shù)據(jù),無(wú)疑是很小的。

  三個(gè)問(wèn)題都導(dǎo)致了網(wǎng)絡(luò)利用率的降低。雖然兩個(gè)問(wèn)題導(dǎo)致了同樣的結(jié)果,但是必須認(rèn)識(shí)到它們是不同的問(wèn)題,很自然的將這些問(wèn)題的解決方案匯總在一起,形成一個(gè)全局的解決方案,這就是如今的操作系統(tǒng)中的解決方案。

  3.問(wèn)題的雜糅情況

  疑難雜癥11:糊涂窗口解決方案和Nagle算法

  糊涂窗口綜合癥患者希望發(fā)送端積累TCP分段,而Nagle算法確實(shí)保證了一定的TCP分段在發(fā)送端的積累,另外在延遲ACK的延遲的那一會(huì)時(shí)間,發(fā)送端會(huì)利用這段時(shí)間積累數(shù)據(jù)。然而這卻是三個(gè)不同的問(wèn)題。Nagle算法可以緩解糊涂窗口綜合癥,卻不是治本的良藥。

  疑難雜癥12:Nagle算法和延遲ACK

  延遲ACK會(huì)延長(zhǎng)ACK到達(dá)發(fā)送端的時(shí)間,由于標(biāo)準(zhǔn)Nagle算法只允許一個(gè)未被確認(rèn)的TCP分段,那無(wú)疑在接收端,這個(gè)延遲的ACK是毫無(wú)希望等待后續(xù)數(shù)據(jù)到來(lái)最終進(jìn)行積累確認(rèn)的,如果沒(méi)有數(shù)據(jù)可以捎帶這個(gè)ACK,那么這個(gè)ACK只有在延遲確認(rèn)定時(shí)器超時(shí)的時(shí)候才會(huì)發(fā)出,這樣在等待這個(gè)ACK的過(guò)程中,發(fā)送端又積累了一些數(shù)據(jù),因此延遲ACK實(shí)際上是在增加延遲的代價(jià)下加強(qiáng)了Nagle算法。在延遲ACK加Nagle算法的情況下,接收端只有不斷有數(shù)據(jù)要發(fā)回,才能同時(shí)既保證了發(fā)送端的分段積累,又保證了延遲不增加,同時(shí)還沒(méi)有或者很少有空載的ACK。

  要知道,延遲ACK和Nagle是兩個(gè)問(wèn)題的解決方案。

  疑難雜癥13:到底何時(shí)可以發(fā)送數(shù)據(jù)

  到底何時(shí)才能發(fā)送數(shù)據(jù)呢?如果單從Nagle算法上看,很簡(jiǎn)單,然而事實(shí)證明,情況還要更復(fù)雜些。如果發(fā)送端已經(jīng)排列了3個(gè)TCP分段,分段1,分段2,分段3依次被排入,三個(gè)分段都是小分段(不符合Nagle算法中立即發(fā)送的標(biāo)準(zhǔn)),此時(shí)已經(jīng)有一個(gè)分段被發(fā)出了,且其確認(rèn)還沒(méi)有到來(lái),請(qǐng)問(wèn)此時(shí)能發(fā)送分段1 和2嗎?如果按照Nagle算法,是不能發(fā)送的,但實(shí)際上它們是可以發(fā)送的,因?yàn)檫@兩個(gè)分段已經(jīng)沒(méi)有任何機(jī)會(huì)再積累新的數(shù)據(jù)了,新的數(shù)據(jù)肯定都積累在分段 3上了。問(wèn)題在于,分段還沒(méi)有積累到一定大小時(shí),怎么還可以產(chǎn)生新的分段?這是可能的,但這是另一個(gè)問(wèn)題,在此不談。

  Linux的TCP實(shí)現(xiàn)在這個(gè)問(wèn)題上表現(xiàn)的更加靈活,它是這么判斷能否發(fā)送的(在開(kāi)啟了Nagle的情況下):

  IF (沒(méi)有超過(guò)擁塞窗口大小的數(shù)據(jù)分段未確認(rèn) || 數(shù)據(jù)分段中包含F(xiàn)IN ) &&

  數(shù)據(jù)分段沒(méi)有超越窗口邊界

  Then

  IF 分段在中間(上述例子中的分段1和2) ||

  分段是緊急模式 ||

  通過(guò)上述的Nagle算法(改進(jìn)后的Nagle算法)

  Then 發(fā)送分段

  EndIF

  EndIF

  曾經(jīng)我也改過(guò)Nagle算法,確切的說(shuō)不是修改Nagle算法,而是修改了“到底何時(shí)能發(fā)送數(shù)據(jù)”的策略,以往都是發(fā)送端判斷能否發(fā)送數(shù)據(jù)的,可是如果此時(shí)有延遲ACK在等待被捎帶,而待發(fā)送的數(shù)據(jù)又由于積累不夠或者其它原因不能發(fā)送,因此兩邊都在等,這其實(shí)在某些情況下不是很好。我所做的改進(jìn)中對(duì)待何時(shí)能發(fā)送數(shù)據(jù)又增加了一種情況,這就是“ACK拉”的情況,一旦有延遲ACK等待發(fā)送,判斷一下有沒(méi)有數(shù)據(jù)也在等待發(fā)送,如果有的話,看看數(shù)據(jù)是否大到了一定程度,在此,我選擇的是MSS的一半:

  IF (沒(méi)有超過(guò)擁塞窗口大小的數(shù)據(jù)分段未確認(rèn) || 數(shù)據(jù)分段中包含F(xiàn)IN ) &&

  數(shù)據(jù)分段沒(méi)有超越窗口邊界

  Then

  IF 分段在中間(上述例子中的分段1和2) ||

  分段是緊急模式 ||

  通過(guò)上述的Nagle算法(改進(jìn)后的Nagle算法)

  Then 發(fā)送分段

  EndIF

  ELSE IF 有延遲ACK等待傳輸 &&

  發(fā)送隊(duì)列中有待發(fā)送的TCP分段 &&

  發(fā)送隊(duì)列的頭分段大小大于MSS的一半

  Then 發(fā)送隊(duì)列頭分段且捎帶延遲ACK

  EndIF

  另外,發(fā)送隊(duì)列頭分段的大小是可以在統(tǒng)計(jì)意義上動(dòng)態(tài)計(jì)算的,也不一定非要是MSS大小的一半。我們發(fā)現(xiàn),這種算法對(duì)于交互式網(wǎng)路應(yīng)用是自適應(yīng)的,你打字越快,特定時(shí)間內(nèi)積累的分段就越長(zhǎng),對(duì)端回復(fù)的越快(可以捎帶ACK),本端發(fā)送的也就越快(以Echo舉例會(huì)更好理解)。

  疑難雜癥14:《TCP/IP詳解(卷一)》中Nagle算法的例子解讀

  這個(gè)問(wèn)題在網(wǎng)上搜了很多的答案,有的說(shuō)RFC的建議,有的說(shuō)別的?墒菍(shí)際上這就是一個(gè)典型的“競(jìng)態(tài)問(wèn)題”:

  首先服務(wù)器發(fā)了兩個(gè)分段:

  數(shù)據(jù)段12:ack 14

  數(shù)據(jù)段13:ack 14,54:56

  然后客戶端發(fā)了兩個(gè)分段:

  數(shù)據(jù)段14:ack 54,14:17

  數(shù)據(jù)段15:ack 56,17:18

  可以看到數(shù)據(jù)段14本來(lái)應(yīng)該確認(rèn)56的,但是確認(rèn)的卻是54。也就是說(shuō),數(shù)據(jù)段已經(jīng)移出隊(duì)列將要發(fā)送但還未發(fā)送的時(shí)候,數(shù)據(jù)段13才到來(lái),軟中斷處理程序搶占了數(shù)據(jù)段14的發(fā)送進(jìn)程,要知道此時(shí)只是把數(shù)據(jù)段14移出了隊(duì)列,還沒(méi)有更新任何的狀態(tài)信息,比如“發(fā)出但未被確認(rèn)的分段數(shù)量”,此時(shí)軟中斷處理程序順利接收了分段13,然后更新窗口信息,并且檢查看有沒(méi)有數(shù)據(jù)要發(fā)送,由于分段14已經(jīng)移出隊(duì)列,下一個(gè)接受發(fā)送檢查的就是分段15了,由于狀態(tài)信息還沒(méi)有更新,因此分段15順利通過(guò)發(fā)送檢測(cè),發(fā)送完成。

  可以看Linux的源代碼了解相關(guān)信息,tcp_write_xmit這個(gè)函數(shù)在兩個(gè)地方會(huì)被調(diào)用,一個(gè)是TCP的發(fā)送進(jìn)程中,另一個(gè)就是軟中斷的接收處理中,兩者在調(diào)用中的競(jìng)態(tài)就會(huì)引起《詳解》中的那種情況。注意,這種不加鎖的發(fā)送方式是合理的,也是效的,因此TCP的處理語(yǔ)義會(huì)做出判斷,丟棄一切不該接收或者重復(fù)接收的分段的。