国产做无码视频在线观看,国产精品日产欧美久久久,国产乱码精品一品二品,国产精品久久久夜夜高潮,国产精品爽爽va在线观看

您的位置:首頁 > 滾動 >

今日精選:圖解 | 你管這破玩意兒叫 TCP?

2022-09-24 15:49:01 來源:指股網(wǎng)


【資料圖】

本文來自微信公眾號:你是一臺電腦,你的名字叫A經(jīng)過《這就是物理層、數(shù)據(jù)鏈路層、網(wǎng)絡層這三層所做的事情。站在第四層的你,就可以不要臉地利用下三層所做的鋪墊,隨心所欲地發(fā)送數(shù)據(jù),而不必擔心找不到對方了。雖然你此時還什么都沒干,但你還是給自己這一層起了個響亮的名字,叫做傳輸層。你本以為自己所在的第四層萬事大吉,啥事沒有,但很快問題就接踵而至。問題來了前三層協(xié)議只能把數(shù)據(jù)包從一個主機搬到另外一臺主機,但是,到了目的地以后,數(shù)據(jù)包具體交給哪個程序(進程)呢?所以,你需要把通信的進程區(qū)分開來,于是就給每個進程分配一個數(shù)字編號,你給它起了一個響亮的名字:端口號。然后你在要發(fā)送的數(shù)據(jù)包上,增加了傳輸層的頭部,源端口號與目標端口號。OK,這樣你將原本主機到主機的通信,升級為了進程和進程之間的通信。你沒有意識到,你不知不覺實現(xiàn)了UDP協(xié)議!(當然UDP協(xié)議中不光有源端口和目標端口,還有數(shù)據(jù)包長度和校驗值,我們暫且略過)就這樣,你用UDP協(xié)議無憂無慮地同B進行著通信,一直沒發(fā)生什么問題。但很快,你發(fā)現(xiàn)事情變得非常復雜......丟包問題由于網(wǎng)絡的不可靠,數(shù)據(jù)包可能在半路丟失,而A和B卻無法察覺。對于丟包問題,只要解決兩個事就好了。第一個,A怎么知道包丟了?答案:讓B告訴A第二個,丟了的包怎么辦?答案:重傳于是你設計了如下方案,A每發(fā)一個包,都必須收到來自B的確認(ACK),再發(fā)下一個,否則在一定時間內(nèi)沒有收到確認,就重傳這個包。你管它叫停止等待協(xié)議。只要按照這個協(xié)議來,雖然A無法保證B一定能收到包,但A能夠確認B是否收到了包,收不到就重試,盡最大努力讓這個通信過程變得可靠,于是你們現(xiàn)在的通信過程又有了一個新的特征,可靠交付。效率問題停止等待雖然能解決問題,但是效率太低了,A原本可以在發(fā)完第一個數(shù)據(jù)包之后立刻開始發(fā)第二個數(shù)據(jù)包,但由于停止等待協(xié)議,A必須等數(shù)據(jù)包到達了B,且B的ACK包又回到了A,才可以繼續(xù)發(fā)第二個數(shù)據(jù)包,這效率慢得可不是一點兩點。于是你對這個過程進行了改進,采用流水線的方式,不再傻傻地等。順序問題但是網(wǎng)路是復雜的、不可靠的。有的時候A發(fā)出去的數(shù)據(jù)包,分別走了不同的路由到達B,可能無法保證和發(fā)送數(shù)據(jù)包時一樣的順序。在流水線中有多個數(shù)據(jù)包和ACK包在亂序流動,他們之間對應關系就亂掉了。難道還回到停止等待協(xié)議?A每收到一個包的確認(ACK)再發(fā)下一個包,那就根本不存在順序問題。應該有更好的辦法!A在發(fā)送的數(shù)據(jù)包中增加一個序號(seq),同時B要在ACK包上增加一個確認號(ack),這樣不但解決了停止等待協(xié)議的效率問題,也通過這樣標序號的方式解決了順序問題。而B這個確認號意味深長:比如B發(fā)了一個確認號為ack=3,它不僅僅表示A發(fā)送的序號為2的包收到了,還表示2之前的數(shù)據(jù)包都收到了。這種方式叫累計確認或累計應答。注意,實際上ack的號是收到的最后一個數(shù)據(jù)包的序號seq+1,也就是告訴對方下一個應該發(fā)的序號是多少。但圖中為了便于理解,ack就表示收到的那個序號,不必糾結(jié)。流量問題有的時候,A發(fā)送數(shù)據(jù)包的速度太快,而B的接收能力不夠,但B卻沒有告知A這個情況。怎么解決呢?很簡單,B告訴A自己的接收能力,A根據(jù)B的接收能力,相應控制自己的發(fā)送速率,就好了。B怎么告訴A呢?B跟A說"我很強"這三個字么?那肯定不行,得有一個嚴謹?shù)囊?guī)范。于是B決定,每次發(fā)送數(shù)據(jù)包給A時,順帶傳過來一個值,叫窗口大?。╳in),這個值就表示B的接收能力。同理,每次A給B發(fā)包時也帶上自己的窗口大小,表示A的接收能力。B告訴了A自己的窗口大小值,A怎么利用它去做A這邊發(fā)包的流量控制呢?很簡單,假如B給A傳過來的窗口大小win=5,那A根據(jù)這個值,把自己要發(fā)送的數(shù)據(jù)分成這么幾類。圖片過于清晰,就不再文字解釋了。當A不斷發(fā)送數(shù)據(jù)包時,已發(fā)送的最后一個序號就往右移動,直到碰到了窗口的上邊界,此時A就無法繼續(xù)發(fā)包,達到了流量控制。但是當A不斷發(fā)包的同時,A也會收到來自B的確認包,此時整個窗口會往右移動,因此上邊界也往右移動,A就能發(fā)更多的數(shù)據(jù)包了。以上都是在窗口大小不變的情況下,而B在發(fā)給A的ACK包中,每一個都可以重新設置一個新的窗口大小,如果A收到了一個新的窗口大小值,A會隨之調(diào)整。如果A收到了比原窗口值更大的窗口大小,比如win=6,則A會直接將窗口上邊界向右移動1個單位。如果A收到了比原窗口值小的窗口大小,比如win=4,則A暫時不會改變窗口大小,更不會將窗口上邊界向左移動,而是等著ACK的到來,不斷將左邊界向右移動,直到窗口大小值收縮到新大小為止。OK,終于將流量控制問題解決得差不多了,你看著上面一個個小動圖,給這個窗口起了一個更生動的名字,滑動窗口。擁塞問題但有的時候,不是B的接受能力不夠,而是網(wǎng)絡不太好,造成了網(wǎng)絡擁塞。擁塞控制與流量控制有些像,但流量控制是受B的接收能力影響,而擁塞控制是受網(wǎng)絡環(huán)境的影響。擁塞控制的解決辦法依然是通過設置一定的窗口大小,只不過,流量控制的窗口大小是B直接告訴A的,而擁塞控制的窗口大小按理說就應該是網(wǎng)絡環(huán)境主動告訴A。但網(wǎng)絡環(huán)境怎么可能主動告訴A呢?只能A單方面通過試探,不斷感知網(wǎng)絡環(huán)境的好壞,進而確定自己的擁塞窗口的大小。擁塞窗口大小的計算有很多復雜的算法,就不在本文中展開了,假如擁塞窗口的大小為cwnd,上一部分流量控制的滑動窗口的大小為rwnd,那么窗口的右邊界受這兩個值共同的影響,需要取它倆的最小值。窗口大小=min(cwnd,rwnd)含義很容易理解,當B的接受能力比較差時,即使網(wǎng)絡非常通暢,A也需要根據(jù)B的接收能力限制自己的發(fā)送窗口。當網(wǎng)絡環(huán)境比較差時,即使B有很強的接收能力,A也要根據(jù)網(wǎng)絡的擁塞情況來限制自己的發(fā)送窗口。正所謂受其短板的影響嘛~連接問題有的時候,B主機的相應進程還沒有準備好或是掛掉了,A就開始發(fā)送數(shù)據(jù)包,導致了浪費。這個問題在于,A在跟B通信之前,沒有事先確認B是否已經(jīng)準備好,就開始發(fā)了一連串的信息。就好比你和另一個人打電話,你還沒有"喂"一下確認對方有沒有在聽,你就巴拉巴拉說了一堆。這個問題該怎么解決呢?地球人都知道,三次握手嘛!A:我準備好了(SYN)B:我知道了(ACK),我也準備好了(SYN)A:我知道了(ACK)A與B各自在內(nèi)存中維護著自己的狀態(tài)變量,三次握手之后,雙方的狀態(tài)都變成了連接已建立(ESTABLISHED)。雖然就只是發(fā)了三次數(shù)據(jù)包,并且在各自的內(nèi)存中維護了狀態(tài)變量,但這么說總覺得太low,你看這個過程相當于雙方建立連接的過程,于是你靈機一動,就叫它面向連接吧。注意:這個連接是虛擬的,是由A和B這兩個終端共同維護的,在網(wǎng)絡中的設備根本就不知道連接這回事兒!但凡事有始就有終,有了建立連接的過程,就要考慮釋放連接的過程,又是地球人都知道,四次揮手嘛!A:再見,我要關閉了(FIN)B:我知道了(ACK)給B一段時間把自己的事情處理完...B:再見,我要關閉了(FIN)A:我知道了(ACK)總結(jié)以上講述的,就是TCP協(xié)議的核心思想,上面過程中需要傳輸?shù)男畔?,就體現(xiàn)在TCP協(xié)議的頭部,這里放上最常見的TCP協(xié)議頭解讀的圖。不知道你現(xiàn)在再看下面這句話,是否能理解:TCP是面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議面向連接、可靠,這兩個詞通過上面的講述很容易理解,那什么叫做基于字節(jié)流呢?很簡單,TCP在建立連接時,需要告訴對方MSS(最大報文段大?。?。也就是說,如果要發(fā)送的數(shù)據(jù)很大,在TCP層是需要按照MSS來切割成一個個的TCP報文段的。切割的時候我才不管你原來的數(shù)據(jù)表示什么意思,需要在哪里斷句啥的,我就把它當成一串毫無意義的字節(jié),在我想要切割的地方咔嚓就來一刀,標上序號,只要接收方再根據(jù)這個序號拼成最終想要的完整數(shù)據(jù)就行了。在我TCP傳輸這里,我就把它當做一個個的字節(jié),也就是基于字節(jié)流的含義了。最后留給大家一個作業(yè),模擬A與B建立一個TCP連接。第一題:A給B發(fā)送"aaa",然后B給A回復一個簡單的字符串"success",并將此過程抓包。第二題:A給B發(fā)送"aaaaaa...a"超過最大報文段大小,然后B給A回復一個簡單的字符串"success",并將此過程抓包。下面是我抓的包(第二題)三次握手階段A->B[SYN]Seq=0Win=64240Len=0MSS=1460WS=256B->A[SYN,ACK]Seq=0Ack=1Win=29200Len=0MSS=1424WS=512A->B[ACK]Seq=1Ack=1Win=132352Len=0數(shù)據(jù)發(fā)送階段A->B[ACK]Seq=1Ack=1Win=132352Len=1424A->B[ACK]Seq=1425Ack=1Win=132352Len=1424A->B[PSH,ACK]Seq=2849Ack=1Win=132352Len=1247B->A[ACK]Seq=1Ack=1425Win=32256Len=0B->A[ACK]Seq=1Ack=2849Win=35328Len=0B->A[ACK]Seq=1Ack=4096Win=37888Len=0B->A[PSH,ACK]Seq=1Ack=4096Win=37888Len=7四次揮手階段B->A[FIN,ACK]Seq=8Ack=4096Win=37888Len=0A->B[ACK]Seq=4096Ack=9Win=132352Len=0A->B[FIN,ACK]Seq=4096Ack=9Win=132352Len=0(下面少復制了一行ACK,抱歉)后記一提到TCP,可能很多人都想起被三次握手和四次揮手所支配的恐懼。但其實你跟著文中的思路你就會發(fā)現(xiàn),三次握手與四次揮手只占TCP所解決的核心問題中很小的一部分,只是因為它在面試中很適合作為知識點進行考察,所以在很多人的印象中就好像TCP的核心就是握手和揮手似的。本文希望你能從問題出發(fā),真正理解TCP所想要解決的問題,你會發(fā)現(xiàn)很多原理就好像生活常識一樣順其自然,并不復雜,希望你有收獲~

最近更新