我們知道IP只是“盡力”舆绎,并不保證可靠性,所以傳輸可靠性必須由TCP來完成们颜。
怎么保證可靠呢亿蒸?TCP提供了亂序重排、應(yīng)答確認(rèn)掌桩、報(bào)文重傳和流量控制四種機(jī)制边锁。
亂序重排、應(yīng)答確認(rèn)都跟序號(hào)有關(guān)波岛。由于網(wǎng)絡(luò)或“多線程”等因素茅坛,接收方收到的數(shù)據(jù)段很可能是亂序的,不過则拷,因?yàn)槊總€(gè)TCP封裝都有序號(hào)贡蓖,接收方重組起來非常容易。
發(fā)送方每發(fā)送一個(gè)數(shù)據(jù)段煌茬,如果都等著收到接收方的確認(rèn)后再發(fā)下一個(gè)斥铺,這效率太低了。我們?cè)诮忉孉cknowledgement Number確認(rèn)號(hào)時(shí)坛善,曾舉過一個(gè)栗子晾蜘,發(fā)送方的數(shù)據(jù)有1000字節(jié)邻眷,接收方收到后的確認(rèn)號(hào)填寫1001,是告訴發(fā)送方前面的都收到了剔交,下次從序號(hào)1001開始發(fā)肆饶。
那么,如果發(fā)送方發(fā)送了多個(gè)數(shù)據(jù)段岖常,共5000字節(jié)驯镊,接收方只需發(fā)一個(gè)確認(rèn)號(hào)為5001的報(bào)文,是不是就可以呢竭鞍?
沒錯(cuò)板惑,TCP就是這么干的!這就大大提高了效率偎快。至于一次收多少字節(jié)再發(fā)確認(rèn)冯乘,由接收方window決定。
就好像兩人打電話滨砍,聽對(duì)方說話時(shí)往湿,你時(shí)不時(shí)“嗯”一聲,表示你在聽惋戏。不必對(duì)方每說一句話你就“嗯”领追,當(dāng)然對(duì)方說了半天你不“嗯”也不行,對(duì)方會(huì)問“還在嗎”响逢,是不是這個(gè)理兒绒窑?
TCP的報(bào)文重傳有兩種獨(dú)立的辦法。
一種是超時(shí)重傳舔亭,發(fā)送方收不到確認(rèn)的時(shí)候用些膨。我們都知道網(wǎng)速并不是穩(wěn)定的,傳輸時(shí)的每個(gè)報(bào)文的延時(shí)也不一樣钦铺。TCP會(huì)根據(jù)報(bào)文的往返時(shí)間(RTT)自動(dòng)調(diào)整超時(shí)重傳時(shí)間(RTO)订雾。發(fā)送方每發(fā)一個(gè)報(bào)文段都會(huì)開始計(jì)時(shí),如果時(shí)間超過RTO還沒收到這個(gè)報(bào)文段的確認(rèn)矛洞,就重傳該報(bào)文段洼哎。
另一種方法是快速重傳,發(fā)送的數(shù)據(jù)在路上丟失的時(shí)候用沼本。
我們看下圖:
接收方收到序號(hào)1后噩峦,回復(fù)確認(rèn)號(hào)2,希望下次收到序號(hào)2的報(bào)文段抽兆,但卻亂序收到比序號(hào)2大的3识补、4、5報(bào)文段辫红,于是連續(xù)發(fā)出確認(rèn)號(hào)為2的報(bào)文段凭涂。如果發(fā)送方連續(xù)三次收到重復(fù)的確認(rèn)號(hào)祝辣,立即重發(fā)該報(bào)文段,而不管是否超時(shí)导盅。
接下來较幌,我們討論下TCP中的window窗口揍瑟。
剛才提到過白翻,window可以提高確認(rèn)效率,不必讓接收方為每個(gè)報(bào)文段都發(fā)確認(rèn)绢片。另外滤馍,window還有一個(gè)很重要的作用,那就是流量控制底循。
首先要明白一點(diǎn)巢株,應(yīng)用程序不論發(fā)送還是接收數(shù)據(jù),都會(huì)先把數(shù)據(jù)放入緩沖區(qū)熙涤,再?gòu)木彌_區(qū)中發(fā)出或讀取數(shù)據(jù)阁苞。就像秘書,先把事情整理歸納好祠挫,再一次性向你匯報(bào)那槽。
這個(gè)緩沖區(qū)大小,反映了應(yīng)用程序一次能處理數(shù)據(jù)的能力等舔。如果接收方應(yīng)用程序處理速度比發(fā)送方的發(fā)送速度慢骚灸,就會(huì)造成接收方緩沖區(qū)“溢出”。實(shí)際上慌植,發(fā)送方發(fā)送速度和接收方處理速度很難一致甚牲。
這就需要window來調(diào)整了。
TCP在三次握手建立連接時(shí)蝶柿,會(huì)協(xié)商雙方緩沖區(qū)window大小丈钙。如果因?yàn)榻邮辗教幚硭俣容^慢,接收方會(huì)通過window告知發(fā)送方交汤,實(shí)現(xiàn)動(dòng)態(tài)調(diào)整雏赦,避免“溢出”。
發(fā)送方會(huì)根據(jù)接收方確認(rèn)報(bào)文中的window值來調(diào)整每次發(fā)出多少報(bào)文蜻展,這叫“滑動(dòng)窗口”喉誊。
圖中的“發(fā)送方窗口大小”不僅會(huì)向左“滑動(dòng)”,它的大小也會(huì)根據(jù)網(wǎng)絡(luò)帶寬纵顾、時(shí)延變化及接收方window而動(dòng)態(tài)改變伍茄。關(guān)于這點(diǎn),我們以后在QoS中討論施逾。
TCP把數(shù)據(jù)可靠地傳輸完成后敷矫,還有一個(gè)重要工作例获,拆除連接。就像我們打完電話需要掛斷一樣曹仗。
TCP拆除連接需要“四次揮手”榨汤。
小Q:注意看TCP封裝中的window只占2個(gè)字節(jié),最大僅表示64K字節(jié)的緩沖區(qū)怎茫。這在網(wǎng)絡(luò)早期帶寬非常低收壕、電腦內(nèi)存很小的時(shí)候沒問題。但是現(xiàn)在這個(gè)值早就不夠用了轨蛤。怎么解決這個(gè)問題蜜宪?感興趣的小伙伴可以了解一下window乘積因子。
歡迎留言討論祥山。