一、為什么TCP是可靠傳輸?
1. 停止等待協(xié)議
通過(guò)確認(rèn)與超時(shí)重傳機(jī)制實(shí)現(xiàn)可靠傳輸
在發(fā)送完一個(gè)分組后,必須暫時(shí)保留已發(fā)送的分組的副本。
分組和確認(rèn)分組都必須進(jìn)行編號(hào)。
超時(shí)計(jì)時(shí)器的重傳時(shí)間應(yīng)當(dāng)比數(shù)據(jù)在分組傳輸?shù)钠骄禃r(shí)間更長(zhǎng)一些。
出現(xiàn)差錯(cuò)或丟失的時(shí)候,發(fā)送方會(huì)將自己備份的副本再重傳一次,直到收到接收的確認(rèn)信息。當(dāng)接收方收到重復(fù)的數(shù)據(jù)時(shí),會(huì)直接丟棄,但是會(huì)給發(fā)送方請(qǐng)確認(rèn)自己已經(jīng)收到了。
2. 改進(jìn)的停止等待協(xié)議——連續(xù)ARQ協(xié)議和滑動(dòng)窗口協(xié)議
上面的停止等待協(xié)議每發(fā)送一組數(shù)據(jù)就必須等到接收方回復(fù)確認(rèn)后,再發(fā)起第二組數(shù)據(jù),如果出現(xiàn)超時(shí)重傳的話,效率更低。因此為了提高傳輸?shù)男?,改進(jìn)了等待傳輸協(xié)議。
連續(xù)ARQ協(xié)議和滑動(dòng)窗口協(xié)議的機(jī)制是以接收方回復(fù)確認(rèn)為單位,每次連續(xù)發(fā)送一個(gè)滑動(dòng)窗口指定的數(shù)據(jù)組。示例圖如下:
2.1 什么是滑動(dòng)窗口協(xié)議?(發(fā)送方怎么發(fā)送數(shù)據(jù))
滑動(dòng)窗口是由發(fā)送方維護(hù)的類似指針的變量,在每收到一個(gè)接收方的確認(rèn)消息后,該指針向前移動(dòng)并發(fā)送數(shù)據(jù),到窗口指定大小的數(shù)據(jù)組時(shí)停下,等待接收方的確認(rèn)。示意看圖:
2.2 接收方怎么回復(fù)確認(rèn)?
累積確認(rèn)機(jī)制
發(fā)送方不對(duì)收到的分組逐個(gè)發(fā)送確認(rèn),而是對(duì)按序到達(dá)的最后一個(gè)分組發(fā)送確認(rèn),這樣就表示:到這個(gè)分組為止的所有分組都已正確收到了。
優(yōu)點(diǎn):容易實(shí)現(xiàn),即使確認(rèn)丟失也不必重傳。
缺點(diǎn):不能向發(fā)送方反映出接收方已經(jīng)正確收到的所有分組的信息。
Go-back-N(回退 N)
為了解決上述同一窗口中數(shù)據(jù)組不能完整確認(rèn)的問(wèn)題,連續(xù)ARQ協(xié)議采用了回退機(jī)制。比如說(shuō):發(fā)送方發(fā)送了前 5 個(gè)分組,而中間的第 3 個(gè)分組丟失了。這時(shí)接收方只能對(duì)前兩個(gè)分組發(fā)出確認(rèn)。發(fā)送方無(wú)法知道后面三個(gè)分組的下落,而只好把后面的三個(gè)分組都再重傳一次。這就叫做 Go-back-N(回退 N),表示需要再退回來(lái)重傳已發(fā)送過(guò)的 N 個(gè)分組。
結(jié)論:當(dāng)通信線路質(zhì)量不好時(shí),連續(xù) ARQ 協(xié)議會(huì)帶來(lái)負(fù)面的影響??赡苓€不如傳統(tǒng)的停止等待協(xié)議。
3. TCP可靠傳輸?shù)膶?shí)現(xiàn)
TCP 連接的每一端都必須設(shè)有兩個(gè)窗口——一個(gè)發(fā)送窗口和一個(gè)接收窗口。
TCP 的可靠傳輸機(jī)制用字節(jié)的序號(hào)進(jìn)行控制。TCP 所有的確認(rèn)都是基于序號(hào)而不是基于報(bào)文段。
TCP 兩端的四個(gè)窗口經(jīng)常處于動(dòng)態(tài)變化之中。
TCP連接的往返時(shí)間 RTT 也不是固定不變的。需要使用特定的算法估算較為合理的重傳時(shí)間。
3.1 以字節(jié)為單位的滑動(dòng)窗口技術(shù)
滑動(dòng)窗口是面向字節(jié)流的,為了方便記住每個(gè)分組的序號(hào),下面的圖解以一個(gè)分組假設(shè)100個(gè)字節(jié),為了方便畫圖表示,將分組進(jìn)行編號(hào)簡(jiǎn)化表示,如圖所示,但是要記住,每一個(gè)分組的序號(hào)是多少。
3.2 改進(jìn)的確認(rèn)——選擇確認(rèn)(SACK)
TCP通信時(shí),如果發(fā)送序列中間某個(gè)數(shù)據(jù)包丟失,TCP會(huì)通過(guò)重傳最后確認(rèn)的分組后續(xù)的分組,這樣原先已經(jīng)正確傳輸?shù)姆纸M也可能重復(fù)發(fā)送,降低了TCP性能。SACK(Selective Acknowledgment,選擇確認(rèn))技術(shù),使TCP只重新發(fā)送丟失的包,不用發(fā)送后續(xù)所有的分組,而且提供相應(yīng)機(jī)制使接收方能告訴發(fā)送方哪些數(shù)據(jù)丟失,哪些數(shù)據(jù)已經(jīng)提前收到等。在建立 TCP 連接時(shí),就要在 TCP 首部的選項(xiàng)中加上“允許 SACK”的選項(xiàng),而雙方必須都事先商定好。原來(lái)首部中的“確認(rèn)號(hào)字段”的用法仍然不變。只是以后在 TCP 報(bào)文段的首部中都增加了 SACK 選項(xiàng),以便報(bào)告收到的不連續(xù)的字節(jié)塊的邊界。
選擇性確認(rèn)最多表示4個(gè)邊界:由于首部選項(xiàng)的長(zhǎng)度最多只有 40 字節(jié)。需要一個(gè)字節(jié)指明是SACK選項(xiàng),另一個(gè)字節(jié)指明占多少字節(jié)。而指明一個(gè)邊界就要用掉 4 字節(jié)。在選項(xiàng)中最多只能指明 4 個(gè)字節(jié)塊的邊界信息。因4個(gè)字節(jié)塊共8個(gè)邊界信息。
抓包分析:
3.3 超時(shí)重傳時(shí)間的選擇?
重傳機(jī)制是 TCP 中最重要和最復(fù)雜的問(wèn)題之一。TCP 每發(fā)送一個(gè)報(bào)文段,就對(duì)這個(gè)報(bào)文段設(shè)置一次計(jì)時(shí)器。只要計(jì)時(shí)器設(shè)置的重傳時(shí)間到但還沒(méi)有收到確認(rèn),就要重傳這一報(bào)文段。那么這個(gè)重傳時(shí)間到底應(yīng)該設(shè)置多少呢?這里面有學(xué)問(wèn)。以下是我截取的“手抄報(bào)”,暫時(shí)看不懂。建議跳過(guò)。
加權(quán)平均往返時(shí)間
TCP 保留了 RTT 的一個(gè)加權(quán)平均往返時(shí)間 RTTS(這又稱為平滑的往返時(shí)間)。第一次測(cè)量到 RTT 樣本時(shí),RTTS 值就取為所測(cè)量到的 RTT 樣本值。以后每測(cè)量到一個(gè)新的 RTT 樣本,就按下式重新計(jì)算一次 RTTS:
超時(shí)計(jì)時(shí)器設(shè)置的超時(shí)重傳時(shí)間RTO
往返時(shí)間的測(cè)量
Karn算法
二、TCP的流量控制
流量控制(flow control)就是讓發(fā)送方的發(fā)送速率不要太快,既要讓接收方來(lái)得及接收,也不要使網(wǎng)絡(luò)發(fā)生擁塞。利用滑動(dòng)窗口機(jī)制可以很方便地在 TCP 連接上實(shí)現(xiàn)流量控制。?
流量控制舉例說(shuō)明:
零窗口處理——持續(xù)計(jì)數(shù)器
考慮上面的例子中,當(dāng)A發(fā)送的數(shù)據(jù)已經(jīng)到達(dá)B的接收窗口上限,此時(shí)A就必須等待B處理了部分?jǐn)?shù)據(jù)后,待接收窗口有空閑的時(shí)候,再次發(fā)送數(shù)據(jù),那么A是怎么知道B的接收窗口何時(shí)有空閑呢?這時(shí)就用到了持續(xù)計(jì)時(shí)器。
TCP 為每一個(gè)連接設(shè)有一個(gè)持續(xù)計(jì)時(shí)器。只要 TCP 連接的一方收到對(duì)方的零窗口通知,就啟動(dòng)持續(xù)計(jì)時(shí)器。若持續(xù)計(jì)時(shí)器設(shè)置的時(shí)間到期,就發(fā)送一個(gè)零窗口探測(cè)報(bào)文段(僅攜帶 1 字節(jié)的數(shù)據(jù)),而對(duì)方就在確認(rèn)這個(gè)探測(cè)報(bào)文段時(shí)給出了現(xiàn)在的窗口值。若窗口仍然是零,則收到這個(gè)報(bào)文段的一方就重新設(shè)置持續(xù)計(jì)時(shí)器。若窗口不是零,則死鎖的僵局就可以打破了。
三、TCP的傳輸效率
關(guān)于TCP的傳輸效率問(wèn)題,需要從三方面來(lái)考慮,1.何時(shí)發(fā)送;2.少字節(jié)發(fā)送數(shù)據(jù)問(wèn)題;3.糊涂窗口綜合癥問(wèn)題
3.1 TCP報(bào)文的發(fā)送時(shí)機(jī):
第一種機(jī)制是 TCP 維持一個(gè)變量,它等于最大報(bào)文段長(zhǎng)度 MSS。只要緩存中存放的數(shù)據(jù)達(dá)到 MSS 字節(jié)時(shí),就組裝成一個(gè) TCP 報(bào)文段發(fā)送出去。
第二種機(jī)制是由發(fā)送方的應(yīng)用進(jìn)程指明要求發(fā)送報(bào)文段,即 TCP 支持的推送(push)操作。
第三種機(jī)制是發(fā)送方的一個(gè)計(jì)時(shí)器期限到了,這時(shí)就把當(dāng)前已有的緩存數(shù)據(jù)裝入報(bào)文段(但長(zhǎng)度不能超過(guò) MSS)發(fā)送出去。
3.2 少量字節(jié)發(fā)送數(shù)據(jù)問(wèn)題:
問(wèn)題描述:如果應(yīng)用程序一次產(chǎn)生一字節(jié)數(shù)據(jù),這樣會(huì)導(dǎo)致網(wǎng)絡(luò)由于太多的包而過(guò)載。如:從鍵盤輸入的一個(gè)字符,占用一個(gè)字節(jié),可能在傳輸上造成41字節(jié)的包,其中包括1字節(jié)的有用信息和40字節(jié)的標(biāo)題數(shù)據(jù)。
解決方案(NAGLE算法):發(fā)送端的應(yīng)用進(jìn)程將欲發(fā)送的數(shù)據(jù)逐個(gè)字節(jié)地送到TCP緩存,則發(fā)送端就將第一個(gè)字符先發(fā)送出去。將后面到達(dá)的字符都緩存起來(lái)。當(dāng)接收端收到對(duì)第一個(gè)字符確認(rèn)后,再將緩存中的所有字符裝成一個(gè)報(bào)文段發(fā)送出去,同時(shí)繼續(xù)對(duì)隨后到在的字符進(jìn)行緩存。只有在收到對(duì)前一個(gè)報(bào)文段確認(rèn)后才繼續(xù)發(fā)送下一個(gè)報(bào)文段。
3.3 糊涂窗口綜合癥問(wèn)題:
問(wèn)題描述:設(shè)想一種情況:接收端緩存已滿,而交互式的應(yīng)用進(jìn)程一次只從緩存中讀取一個(gè)字符,然后向發(fā)送端發(fā)送確認(rèn),并將窗口設(shè)置1個(gè)字節(jié)。接著發(fā)送端又發(fā)來(lái)1個(gè)字符。接收端發(fā)回確認(rèn),仍然將窗口設(shè)置為1個(gè)字節(jié)。這樣下去,網(wǎng)絡(luò)效率非常低。
解決方案:接收端等待一段時(shí)間,使得緩存已有足夠空間容納;或者緩存已有一半空的空間,再向發(fā)送端發(fā)送確認(rèn)。
編輯:hfy
評(píng)論
查看更多