0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

計網(wǎng)分層結(jié)構(gòu)

GReq_mcu168 ? 來源:硬件攻城獅 ? 作者:硬件攻城獅 ? 2022-07-13 14:26 ? 次閱讀

/ 計網(wǎng)分層結(jié)構(gòu) / 考慮最簡單的情況:兩臺主機(jī)之間的通信。這個時候只需要一條網(wǎng)線把兩者連起來,規(guī)定好彼此的硬件接口,如都用USB、電壓10v、頻率2.4GHz等,這一層就是物理層,這些規(guī)定就是物理層協(xié)議。

9f9e5680-0272-11ed-ba43-dac502259ad0.png

我們當(dāng)然不滿足于只有兩臺電腦連接,因此我們可以使用交換機(jī)把多個電腦連接起來,如下圖:

9fbbbf5e-0272-11ed-ba43-dac502259ad0.png

這樣連接起來的網(wǎng)絡(luò),稱為局域網(wǎng),也可以稱為以太網(wǎng)(以太網(wǎng)是局域網(wǎng)的一種)。在這個網(wǎng)絡(luò)中,我們需要標(biāo)識每個機(jī)器,這樣才可以指定要和哪個機(jī)器通信。這個標(biāo)識就是硬件地址MAC。硬件地址隨機(jī)器的生產(chǎn)就被確定,永久性唯一。在局域網(wǎng)中,我們需要和另外的機(jī)器通信時,只需要知道他的硬件地址,交換機(jī)就會把我們的消息發(fā)送到對應(yīng)的機(jī)器。 這里我們可以不管底層的網(wǎng)線接口如何發(fā)送,把物理層抽離,在他之上創(chuàng)建一個新的層次,這就是數(shù)據(jù)鏈路層。 我們依然不滿足于局域網(wǎng)的規(guī)模,需要把所有的局域網(wǎng)聯(lián)系起來,這個時候就需要用到路由器來連接兩個局域網(wǎng):

9fcc63f4-0272-11ed-ba43-dac502259ad0.png

但是如果我們還是使用硬件地址來作為通信對象的唯一標(biāo)識,那么當(dāng)網(wǎng)絡(luò)規(guī)模越來越大,需要記住所有機(jī)器的硬件地址是不現(xiàn)實的;同時,一個網(wǎng)絡(luò)對象可能會頻繁更換設(shè)備,這個時候硬件地址表維護(hù)起來更加復(fù)雜。這里使用了一個新的地址來標(biāo)記一個網(wǎng)絡(luò)對象:IP地址。 通過一個簡單的寄信例子來理解IP地址。 我住在北京市,我朋友A住在上海市,我要給朋友A寫信:

寫完信,我會在信上寫好我朋友A的地址,并放到北京市郵局(給信息附加目標(biāo)IP地址,并發(fā)送給路由器)

郵局會幫我把信運輸?shù)缴虾J挟?dāng)?shù)剜]局(信息會經(jīng)過路由傳遞到目標(biāo)IP局域網(wǎng)的路由器)

上海市當(dāng)?shù)芈酚善鲿臀野研沤唤o朋友A(局域網(wǎng)內(nèi)通信)

因此,這里IP地址就是一個網(wǎng)絡(luò)接入地址(朋友A的住址),我只需要知道目標(biāo)IP地址,路由器就可以把消息給我?guī)У?。在局域網(wǎng)中,就可以動態(tài)維護(hù)一個MAC地址與IP地址的映射關(guān)系,根據(jù)目的IP地址就可以尋找到機(jī)器的MAC地址進(jìn)行發(fā)送。 這樣我們不需管理底層如何去選擇機(jī)器,我們只需要知道IP地址,就可以和我們的目標(biāo)進(jìn)行通信。這一層就是網(wǎng)絡(luò)層。網(wǎng)絡(luò)層的核心作用就是提供主機(jī)之間的邏輯通信。這樣,在網(wǎng)絡(luò)中的所有主機(jī),在邏輯上都連接起來了,上層只需要提供目標(biāo)IP地址和數(shù)據(jù),網(wǎng)絡(luò)層就可以把消息發(fā)送到對應(yīng)的主機(jī)。 一個主機(jī)有多個進(jìn)程,進(jìn)程之間進(jìn)行不同的網(wǎng)絡(luò)通信,如邊和朋友開黑邊和女朋友聊微信。我的手機(jī)同時和兩個不同機(jī)器進(jìn)行通信。那么當(dāng)我的手機(jī)收到數(shù)據(jù)時,如何區(qū)分是微信的數(shù)據(jù),還是王者的數(shù)據(jù)?那么就必須在網(wǎng)絡(luò)層之上再添加一層:運輸層:

9fd9bc5c-0272-11ed-ba43-dac502259ad0.png

運輸層通過socket(套接字),將網(wǎng)絡(luò)信息進(jìn)行進(jìn)一步的拆分,不同的應(yīng)用進(jìn)程可以獨立進(jìn)行網(wǎng)絡(luò)請求,互不干擾。這就是運輸層的最本質(zhì)特點:提供進(jìn)程之間的邏輯通信。這里的進(jìn)程可以是主機(jī)之間,也可以是同個主機(jī),所以在android中,socket通信也是進(jìn)程通信的一種方式。 現(xiàn)在不同的機(jī)器上的應(yīng)用進(jìn)程之間可以獨立通信了,那么我們就可以在計算機(jī)網(wǎng)絡(luò)上開發(fā)出形形式式的應(yīng)用:如web網(wǎng)頁的http,文件傳輸ftp等等。這一層稱為應(yīng)用層。 應(yīng)用層還可以進(jìn)一步拆分出表示層、會話層,但他們的本質(zhì)特點都沒有改變:完成具體的業(yè)務(wù)需求。和下面的四層相比,他們并不是必須的,可以歸屬到應(yīng)用層中。 最后對計網(wǎng)分層進(jìn)行小結(jié):

9fe2237e-0272-11ed-ba43-dac502259ad0.png

最底層物理層,負(fù)責(zé)兩個機(jī)器之間通過硬件的直接通信;

數(shù)據(jù)鏈路層使用硬件地址在局域網(wǎng)中進(jìn)行尋址,實現(xiàn)局域網(wǎng)通信;

網(wǎng)絡(luò)層通過抽象IP地址實現(xiàn)主機(jī)之間的邏輯通信;

運輸層在網(wǎng)絡(luò)層的基礎(chǔ)上,對數(shù)據(jù)進(jìn)行拆分,實現(xiàn)應(yīng)用進(jìn)程的獨立網(wǎng)絡(luò)通信;

應(yīng)用層在運輸層的基礎(chǔ)上,根據(jù)具體的需求開發(fā)形形式式的功能。

這里需要注意的是,分層并不是在物理上的分層,而是邏輯上的分層。通過對底層邏輯的封裝,使得上層的開發(fā)可以直接依賴底層的功能而無需理會具體的實現(xiàn),簡便了開發(fā)。 這種分層的思路,也就是責(zé)任鏈設(shè)計模式,通過層層封裝,把不同的職責(zé)獨立起來,更加方便開發(fā)、維護(hù)等等。okHttp中的攔截器設(shè)計模式,也是這種責(zé)任鏈模式。 / 運輸層 / 本文主要是講解TCP,這里需要增加一些運輸層的知識。

本質(zhì):提供進(jìn)程通信

9fea8d16-0272-11ed-ba43-dac502259ad0.png

在運輸層之下的網(wǎng)絡(luò)層,是不知道該數(shù)據(jù)包屬于哪個進(jìn)程,他只負(fù)責(zé)數(shù)據(jù)包的接收與發(fā)送。運輸層則負(fù)責(zé)接收不同進(jìn)程的數(shù)據(jù)交給網(wǎng)絡(luò)層,同時把網(wǎng)絡(luò)層的數(shù)據(jù)拆分交給不同的進(jìn)程。從上往下匯聚到網(wǎng)絡(luò)層,稱為多路復(fù)用,從下往上拆分,稱為多路拆分。 運輸層的表現(xiàn),受網(wǎng)絡(luò)層的限制。這很好理解,網(wǎng)絡(luò)層是運輸層的底層支持。所以運輸層是無法決定自己帶寬、時延等的上限。但可以基于網(wǎng)絡(luò)層開發(fā)更多的特性:如可靠傳輸。網(wǎng)絡(luò)層只負(fù)責(zé)盡力把數(shù)據(jù)包從一端發(fā)送到另一端,而不保證數(shù)據(jù)可以到達(dá)且完整。

底層實現(xiàn):socket

前面講到,最簡單的運輸層協(xié)議,就是提供進(jìn)程之間的獨立通信 ,但底層的實現(xiàn),是socket之間的獨立通信。在網(wǎng)絡(luò)層中,IP地址是一個主機(jī)邏輯地址,而在運輸層中,socket是一個進(jìn)程的邏輯地址;當(dāng)然,一個進(jìn)程可以擁有多個socket。應(yīng)用進(jìn)程可以通過監(jiān)聽socket,來獲取這個socket接受到的消息。

9ff557dc-0272-11ed-ba43-dac502259ad0.png

socket并不是一個實實在在的東西,而是運輸層抽象出來的一個對象。運輸層增加了端口這個概念,來區(qū)分不同的socket。端口可以理解為一個主機(jī)上有很多的網(wǎng)絡(luò)通信口,每個端口都有一個端口號,端口的數(shù)量由運輸層協(xié)議確定。 不同的運輸層協(xié)議對socket有不同的定義方式。在UDP協(xié)議中,使用目標(biāo)IP+目標(biāo)端口號來定義一個socket;在TCP中使用目標(biāo)IP+目標(biāo)端口號+源IP+源端口號來定義一個socket。我們只需要在運輸層報文的頭部附加上這些信息,目標(biāo)主機(jī)就會知道我們要發(fā)送給哪個socket,對應(yīng)監(jiān)聽該socket的進(jìn)程就可獲得信息。

運輸層協(xié)議

運輸層的協(xié)議就是大名鼎鼎的TCP和UDP。其中,UDP是最精簡的運輸層協(xié)議,只實現(xiàn)了進(jìn)程間的通信;而TCP在UDP的基礎(chǔ)上,實現(xiàn)了可靠傳輸、流量控制、擁塞控制、面向連接等等特性,同時也更加復(fù)雜。 當(dāng)然除此之外,還有更多更優(yōu)秀的運輸層協(xié)議,但目前廣為使用的,就是TCP和UDP。UDP在后面也會總結(jié)到。 / TCP協(xié)議首部 / TCP協(xié)議,表現(xiàn)在報文上,就是會在應(yīng)用層傳輸下來的數(shù)據(jù)前附加上一個TCP首部,這個首部附加了TCP信息,先來整體看一下這個首部的結(jié)構(gòu):

a00442e2-0272-11ed-ba43-dac502259ad0.png

這張圖是來自我大學(xué)老師的課件, 非常好用,所以一直拿來學(xué)習(xí)。最下面部分表示了報文之間的關(guān)系,TCP數(shù)據(jù)部分就是應(yīng)用層傳下來的數(shù)據(jù)。 TCP首部固定長度是20字節(jié),下面還有4字節(jié)是可選的。內(nèi)容很多,但其中有一些我們比較熟悉的:源端口,目標(biāo)端口。嗯?socket不是還需要IP進(jìn)行定位嗎?IP地址在網(wǎng)絡(luò)層被附加了。其他的內(nèi)容后面都會慢慢講解,作為一篇總結(jié)文章,這里放出查閱表,方便復(fù)習(xí):

a00e7488-0272-11ed-ba43-dac502259ad0.png

a016af86-0272-11ed-ba43-dac502259ad0.png

選項字段中包含以下其他選項:

a0223cf2-0272-11ed-ba43-dac502259ad0.png

講完下面內(nèi)容,再回來看這些字段就熟悉了。 / TCP面向字節(jié)流特性 / TCP并不是把應(yīng)用層傳輸過來的數(shù)據(jù)直接加上首部然后發(fā)送給目標(biāo),而是把數(shù)據(jù)看成一個字節(jié)流,給他們標(biāo)上序號之后分部分發(fā)送。這就是TCP的面向字節(jié)流特性:

a02d9930-0272-11ed-ba43-dac502259ad0.png

TCP會以流的形式從應(yīng)用層讀取數(shù)據(jù)并存放在自己的發(fā)送緩存區(qū)中,同時為這些字節(jié)標(biāo)上序號

TCP會從發(fā)送方緩沖區(qū)選擇適量的字節(jié)組成TCP報文,通過網(wǎng)絡(luò)層發(fā)送給目標(biāo)

目標(biāo)會讀取字節(jié)并存放在自己的接收方緩沖區(qū)中,并在合適的時候交付給應(yīng)用層

面向字節(jié)流的好處是無需一次存儲過大的數(shù)據(jù)占用太多內(nèi)存,壞處是無法知道這些字節(jié)代表的意義,例如應(yīng)用層發(fā)送一個音頻文件和一個文本文件,對于TCP來說就是一串字節(jié)流,沒有意義可言,這會導(dǎo)致粘包以及拆包問題,后面講。 / 可靠傳輸原理 / 前面講到,TCP是可靠傳輸協(xié)議,也就是,一個數(shù)據(jù)交給他,他肯定可以完整無誤地發(fā)送到目標(biāo)地址,除非網(wǎng)絡(luò)炸了。他實現(xiàn)的網(wǎng)絡(luò)模型如下:

a037a45c-0272-11ed-ba43-dac502259ad0.png

對于應(yīng)用層來說,他就是一個可靠傳輸?shù)牡讓又С址?wù);而運輸層底層采用了網(wǎng)絡(luò)層的不可靠傳輸。雖然在網(wǎng)絡(luò)層甚至數(shù)據(jù)鏈路層就可以使用協(xié)議來保證數(shù)據(jù)傳輸?shù)目煽啃?,但這樣網(wǎng)絡(luò)的設(shè)計會更加復(fù)雜、效率會隨之降低。把數(shù)據(jù)傳輸?shù)目煽啃员WC放在運輸層,會更加合適。 可靠傳輸原理的重點總結(jié)一下有:滑動窗口、超時重傳、累積確認(rèn)、選擇確認(rèn)、連續(xù)ARQ。

停止等待協(xié)議

要實現(xiàn)可靠傳輸,最簡便的方法就是:我發(fā)送一個數(shù)據(jù)包給你,然后你跟我回復(fù)收到,我繼續(xù)發(fā)送下一個數(shù)據(jù)包。傳輸模型如下:

a04f21fe-0272-11ed-ba43-dac502259ad0.png

這種“一來一去”的方法來保證傳輸可靠就是停止等待協(xié)議(stop-and-wait)。不知道還記不記得前面TCP首部有一個ack字段,當(dāng)他設(shè)置為1的時候,表示這個報文是一個確認(rèn)收到報文。 然后再來考慮一種情況:丟包。網(wǎng)絡(luò)環(huán)境不可靠,導(dǎo)致每一次發(fā)送的數(shù)據(jù)包可能會丟失,如果機(jī)器A發(fā)送了數(shù)據(jù)包丟失了,那么機(jī)器B永遠(yuǎn)接收不到數(shù)據(jù),機(jī)器A永遠(yuǎn)在等待。解決這個問題的方法是:超時重傳。當(dāng)機(jī)器A發(fā)出一個數(shù)據(jù)包時便開始計時,時間到還沒收到確認(rèn)回復(fù),就可以認(rèn)為是發(fā)生了丟包,便再次發(fā)送,也就是重傳。 但重傳會導(dǎo)致另一種問題:如果原先的數(shù)據(jù)包并沒有丟失,只是在網(wǎng)絡(luò)中待的時間比較久,這個時候機(jī)器B會受到兩個數(shù)據(jù)包,那么機(jī)器B是如何辨別這兩個數(shù)據(jù)包是屬于同一份數(shù)據(jù)還是不同的數(shù)據(jù)?這就需要前面講過的方法:給數(shù)據(jù)字節(jié)進(jìn)行編號。這樣接收方就可以根據(jù)數(shù)據(jù)的字節(jié)編號,得出這些數(shù)據(jù)是接下來的數(shù)據(jù),還是重傳的數(shù)據(jù)。 在TCP首部有兩個字段:序號和確認(rèn)號,他們表示發(fā)送方數(shù)據(jù)第一個字節(jié)的編號,和接收方期待的下一份數(shù)據(jù)的第一個字節(jié)的編號。前面講到TCP是面向字節(jié)流,但是他并不是一個字節(jié)一個字節(jié)地發(fā)送,而是一次截取一整段。截取的長度受多種因素影響,如緩存區(qū)的數(shù)據(jù)大小、數(shù)據(jù)鏈路層限制的幀大小等。

連續(xù)ARQ協(xié)議

停止等待協(xié)議已經(jīng)可以滿足可靠傳輸了,但有一個致命缺點:效率太低。發(fā)送方發(fā)送一個數(shù)據(jù)包之后便進(jìn)入等待,這個期間并沒有干任何事,浪費了資源。解決的方法是:連續(xù)發(fā)送數(shù)據(jù)包。模型如下:

a05a47d2-0272-11ed-ba43-dac502259ad0.png

和停止等待最大的不同就是,他會源源不斷地發(fā)送,接收方源源不斷收到數(shù)據(jù)之后,逐一進(jìn)行確認(rèn)回復(fù)。這樣便極大地提高了效率。但同樣,帶來了一些額外的問題: 發(fā)送是否可以無限發(fā)送直到把緩沖區(qū)所有數(shù)據(jù)發(fā)送完?不可以。因為需要考慮接收方緩沖區(qū)以及讀取數(shù)據(jù)的能力。如果發(fā)送太快導(dǎo)致接收方無法接受,那么只是會頻繁進(jìn)行重傳,浪費了網(wǎng)絡(luò)資源。所以發(fā)送方發(fā)送數(shù)據(jù)的范圍,需要考慮到接收方緩沖區(qū)的情況。這就是TCP的流量控制。解決方法是:滑動窗口?;灸P腿缦拢?

a070c02a-0272-11ed-ba43-dac502259ad0.png

發(fā)送方需要根據(jù)接收方的緩沖區(qū)大小,設(shè)置自己的可發(fā)送窗口大小,處于窗口內(nèi)的數(shù)據(jù)表示可發(fā)送,之外的數(shù)據(jù)不可發(fā)送。

當(dāng)窗口內(nèi)的數(shù)據(jù)接收到確認(rèn)回復(fù)時,整個窗口會往前移動,直到發(fā)送完成所有的數(shù)據(jù)

在TCP的首部有一個窗口大小字段,他表示接收方的剩余緩沖區(qū)大小,讓發(fā)送方可以調(diào)整自己的發(fā)送窗口大小。通過滑動窗口,就可以實現(xiàn)TCP的流量控制,不至于發(fā)送太快,導(dǎo)致太多的數(shù)據(jù)丟失。 連續(xù)ARQ帶來的第二個問題是:網(wǎng)絡(luò)中充斥著和發(fā)送數(shù)據(jù)包一樣數(shù)據(jù)量的確認(rèn)回復(fù)報文,因為每一個發(fā)送數(shù)據(jù)包,必須得有一個確認(rèn)回復(fù)。提高網(wǎng)絡(luò)效率的方法是:累積確認(rèn)。接收方不需要逐個進(jìn)行回復(fù),而是累積到一定量的數(shù)據(jù)包之后,告訴發(fā)送方,在此數(shù)據(jù)包之前的數(shù)據(jù)全都收到。例如,收到 1234,接收方只需要告訴發(fā)送方我收到4了,那么發(fā)送方就知道1234都收到了。 第三個問題是:如何處理丟包情況。在停止等待協(xié)議中很簡單,直接一個超時重傳就解決了。但,連續(xù)ARQ中不太一樣。例如:接收方收到了 123 567,六個字節(jié),編號為4的字節(jié)丟失了。按照累積確認(rèn)的思路,只能發(fā)送3的確認(rèn)回復(fù),567都必須丟掉,因為發(fā)送方會進(jìn)行重傳。這就是GBN(go-back-n)思路。 但是我們會發(fā)現(xiàn),只需要重傳4即可,這樣不是很浪費資源,所以就有了:選擇確認(rèn)SACK。在TCP報文的選項字段,可以設(shè)置已經(jīng)收到的報文段,每一個報文段需要兩個邊界來進(jìn)行確定。這樣發(fā)送方,就可以根據(jù)這個選項字段只重傳丟失的數(shù)據(jù)了。

可靠傳輸小結(jié)

到這里關(guān)于TCP的可靠傳輸原理就已經(jīng)介紹的差不多。最后進(jìn)行一個小結(jié):

通過連續(xù)ARQ協(xié)議與發(fā)送-確認(rèn)回復(fù)模式來保證每一個數(shù)據(jù)包都到達(dá)接收方

通過給字節(jié)編號的方法,來標(biāo)記每一個數(shù)據(jù)是屬于重傳還是新的數(shù)據(jù)

通過超時重傳的方式,來解決數(shù)據(jù)包在網(wǎng)絡(luò)中丟失的問題

通過滑動窗口來實現(xiàn)流量控制

通過累積確認(rèn)+選擇確認(rèn)的方法來提高確認(rèn)回復(fù)與重傳的效率

當(dāng)然,這只是可靠傳輸?shù)谋揭唤?,感興趣可以再深入去研究(和面試官聊天已經(jīng)差不多了[狗頭])。 / 擁塞控制 / 擁塞控制考慮的是另外一個問題:避免網(wǎng)絡(luò)過分擁擠導(dǎo)致丟包嚴(yán)重,網(wǎng)絡(luò)效率降低。 拿現(xiàn)實的交通舉例子: 高速公路同一時間可通行的汽車數(shù)量是一定的,當(dāng)節(jié)假日時,就會發(fā)生嚴(yán)重的堵車。在TCP中,數(shù)據(jù)包超時,會進(jìn)行重傳,也就是會進(jìn)來更多的汽車,這時候更堵,最后導(dǎo)致的結(jié)果就是:丟包-重傳-丟包-重傳。最后整個網(wǎng)絡(luò)癱瘓了。 這里的擁塞控制和前面的流量控制不是一個東西,流量控制是擁塞控制的手段:為了避免擁塞,必須對流量進(jìn)行控制。擁塞控制目的是:限制每個主機(jī)的發(fā)送的數(shù)據(jù)量,避免網(wǎng)絡(luò)擁塞效率下降。就像廣州等地,限制車牌號出行是一個道理。不然大家都堵在路上,誰都別想走。 擁塞控制的解決方法是流量控制,流量控制的實現(xiàn)是滑動窗口,所以擁塞控制最終也是通過限制發(fā)送方的滑動窗口大小來限制流量。當(dāng)然,擁塞控制的手段不只是流量控制,導(dǎo)致?lián)砣囊蛩赜校郝酚善骶彺?、帶寬?a target="_blank">處理器處理速度等等。提升硬件能力(把4車道改成8車道)是其中一個方法,但畢竟硬件提升是有瓶頸的,沒辦法不斷提升,還是需要從tcp本身來增加算法,解決擁塞。 擁塞控制的重點有4個:慢開始、快恢復(fù)、快重傳、擁塞避免。這里依舊獻(xiàn)祭出大學(xué)老師的ppt圖片:

a07f9820-0272-11ed-ba43-dac502259ad0.png

Y軸表示的是發(fā)送方窗口大小,X軸表示的是發(fā)送的輪次(不是字節(jié)編號)。

最開始的時候,會把窗口設(shè)置一個較小的值,然后每輪變?yōu)樵瓉淼膬杀丁_@是慢開始。

當(dāng)窗口值到達(dá)ssthresh值,這個值是需要通過實時網(wǎng)絡(luò)情況設(shè)置的一個窗口限制值,開始進(jìn)入擁塞避免,每輪把窗口值提升1,慢慢試探網(wǎng)絡(luò)的底線。

如果發(fā)生了數(shù)據(jù)超時,表示極可能發(fā)生了擁塞,然后回到慢開始,重復(fù)上面的步驟。

如果收到三個相同的確認(rèn)回復(fù),表示現(xiàn)在網(wǎng)絡(luò)的情況不太好,把ssthresh的值設(shè)置為原來的一半,繼續(xù)擁塞避免。這部分稱為快恢復(fù)。

如果收到丟包信息,應(yīng)該盡快把丟失的包重傳一次,這是快重傳。

當(dāng)然,窗口的最終上限是不能無限上漲的,他不能超過接收方的緩存區(qū)大小。

通過這個算法,就可以在很大程度上,避免網(wǎng)絡(luò)擁擠。 除此之外,還可以讓路由器在緩存即將滿的時候,告知發(fā)送方我快滿了,而不是等到出現(xiàn)了超時再進(jìn)行處理,這是主動隊列管理AQM。此外還有很多方法,但是上面的算法是重點。 / 面向連接 / 這一小節(jié)講的就是無人不曉的TCP三次握手與四次揮手這些,經(jīng)過前面的內(nèi)容,這一小節(jié)其實已經(jīng)很好理解。 TCP是面向連接的,那連接是什么?這里的連接并不是實實在在的連接,而是通信雙方彼此之間的一個記錄。TCP是一個全雙工通信,也就是可以互相發(fā)送數(shù)據(jù),所以雙方都需要記錄對方的信息。根據(jù)前面的可靠傳輸原理,TCP通信雙方需要為對方準(zhǔn)備一個接收緩沖區(qū)可以接收對方的數(shù)據(jù)、記住對方的socket知道怎么發(fā)送數(shù)據(jù)、記住對方的緩沖區(qū)來調(diào)整自己的窗口大小等等,這些記錄,就是一個連接。 在運輸層小節(jié)中講到,運輸層雙方通信的地址是采用socket來定義的,TCP也不例外。TCP的每一個連接只能有兩個對象,也就是兩個socket,而不能有三個。所以socket的定義需要源IP、源端口號、目標(biāo)IP、目標(biāo)端口號四個關(guān)鍵因素,才不會發(fā)生混亂。

假如TCP和UDP一樣只采用目標(biāo)IP+目標(biāo)端口號來定義socket,那么就會出現(xiàn)多個發(fā)送方同時發(fā)送到同一個目標(biāo)socket的情況。這個時候TCP無法區(qū)分這些數(shù)據(jù)是否來自不同的發(fā)送方,就會導(dǎo)致出現(xiàn)錯誤。

既然是連接,就有兩個關(guān)鍵要點:建立連接、斷開連接。

建立連接

建立連接的目的就是交換彼此的信息,然后記住對方的信息。所以雙方都需要發(fā)送彼此的信息給對方:

a092f21c-0272-11ed-ba43-dac502259ad0.png

但前面的可靠傳輸原理告訴我們,數(shù)據(jù)在網(wǎng)絡(luò)中傳輸是不可靠的,需要對方給予我們一個確認(rèn)回復(fù),才可以保證消息正確到達(dá)。如下圖:

a0a16900-0272-11ed-ba43-dac502259ad0.png

機(jī)器B的確認(rèn)收到和機(jī)器B信息可以進(jìn)行合并,減少次數(shù);而且發(fā)送機(jī)器B給機(jī)器A本身就代表了機(jī)器B已經(jīng)收到了消息,所以最后的示例圖是:

a0a949e0-0272-11ed-ba43-dac502259ad0.png

步驟如下:

機(jī)器A發(fā)送syn包向機(jī)器B請求建立TCP連接,并附加上自身的接收緩沖區(qū)信息等,機(jī)器A進(jìn)入SYN_SEND狀態(tài),表示請求已經(jīng)發(fā)送正在等待回復(fù);

機(jī)器B收到請求之后,根據(jù)機(jī)器A的信息記錄下來,并創(chuàng)建自身的接收緩存區(qū),向機(jī)器A發(fā)送syn+ack的合成包,同時自身進(jìn)入SYN_RECV狀態(tài),表示已經(jīng)準(zhǔn)備好了,等待機(jī)器A 的回復(fù)就可以向A發(fā)送數(shù)據(jù);

機(jī)器A收到回復(fù)之后記錄機(jī)器B 的信息,發(fā)送ack信息,自身進(jìn)入ESTABLISHED狀態(tài),表示已經(jīng)完全準(zhǔn)備好了,可以進(jìn)行發(fā)送和接收;

機(jī)器B收到ACK數(shù)據(jù)之后,進(jìn)入ESTABLISHED狀態(tài)。

三次消息的發(fā)送,稱為三次握手。

斷開連接

斷開連接和三次握手類似,直接上圖:

a0b376b8-0272-11ed-ba43-dac502259ad0.png

1. 機(jī)器A發(fā)送完數(shù)據(jù)之后,向機(jī)器B請求斷開連接,自身進(jìn)入FIN_WAIT_1狀態(tài),表示數(shù)據(jù)發(fā)送完成且已經(jīng)發(fā)送FIN包(FIN標(biāo)志位為1); 2. 機(jī)器B收到FIN包之后,回復(fù)ack包表示已經(jīng)收到,但此時機(jī)器B可能還有數(shù)據(jù)沒發(fā)送完成,自身進(jìn)入CLOSE_WAIT狀態(tài),表示對方已發(fā)送完成且請求關(guān)閉連接,自身發(fā)送完成之后可以關(guān)閉連接; 3. 機(jī)器B數(shù)據(jù)發(fā)送完成之后,發(fā)送FIN包給機(jī)器B ,自身進(jìn)入LAST_ACK狀態(tài),表示等待一個ACK包即可關(guān)閉連接; 4. 機(jī)器A收到FIN包之后,知道機(jī)器B也發(fā)送完成了,回復(fù)一個ACK包,并進(jìn)入TIME_WAIT狀態(tài) TIME_WAIT狀態(tài)比較特殊。當(dāng)機(jī)器A收到機(jī)器B的FIN包時,理想狀態(tài)下,確實是可以直接關(guān)閉連接了;但是:

我們知道網(wǎng)絡(luò)是不穩(wěn)定的,可能機(jī)器B 發(fā)送了一些數(shù)據(jù)還沒到達(dá)(比FIN包慢);

同時回復(fù)的ACK包可能丟失了,機(jī)器B會重傳FIN包;

如果此時機(jī)器A馬上關(guān)閉連接,會導(dǎo)致數(shù)據(jù)不完整、機(jī)器B無法釋放連接等問題。所以此時機(jī)器A需要等待2個報文生存最大時長,確保網(wǎng)絡(luò)中沒有任何遺留報文了,再關(guān)閉連接 5. 最后,機(jī)器A等待兩個報文存活最大時長之后,機(jī)器B 接收到ACK報文之后,均關(guān)閉連接,進(jìn)入CLASED狀態(tài) 雙方之間4次互相發(fā)送報文來斷開連接的過程,就是四次揮手。 現(xiàn)在,對于為什么握手是三次揮手是四次、一定要三次/四次嗎、為什么要停留2msl再關(guān)閉連接等等這些問題,就都解決了。 / UDP協(xié)議 / 運輸層協(xié)議除了TCP,還有大名鼎鼎的UDP。如果說TCP憑借他完善穩(wěn)定的功能獨樹一幟,那UDP就是精簡主義亂拳打死老師傅。 UDP只實現(xiàn)了運輸層最少的功能:進(jìn)程間通信。對于應(yīng)用層傳下來的數(shù)據(jù),UDP只是附加一個首部就直接交給網(wǎng)絡(luò)層了。UDP的頭部非常簡單,只有三部分:

源端口、目標(biāo)端口:端口號用來區(qū)分主機(jī)的不同進(jìn)程

校驗碼:用于校驗數(shù)據(jù)包在傳輸?shù)倪^程中沒有出現(xiàn)錯誤,例如某個1變成了0

長度:報文的長度

所以UDP的功能也只有兩個:校驗數(shù)據(jù)報是否發(fā)生錯誤、區(qū)分不同的進(jìn)程通信。 但,TCP的功能雖然多,但同時也是要付出相對應(yīng)的代價。例如面向連接的特性,在建立和斷開連接的時候會有開銷;擁塞控制的特性,會限制傳輸?shù)纳舷薜鹊取O旅鎭砹_列一下UDP的優(yōu)缺點:

UDP的缺點

無法保證消息完整、正確到達(dá),UDP是一個不可靠的傳輸協(xié)議;

缺少擁塞控制容易互相競爭資源導(dǎo)致網(wǎng)絡(luò)系統(tǒng)癱瘓

UDP的優(yōu)點

效率更快;不需要建立連接以及擁塞控制

連接更多的客戶;沒有連接狀態(tài),不需要為每個客戶創(chuàng)建緩存等

分組首部字節(jié)少,開銷小;TCP首部固定首部是20字節(jié),而UDP只有8字節(jié);更小的首部意味著更大比例的數(shù)據(jù)部分

在一些需要高效率允許可限度誤差的場景下可以使用。如直播場景,并不需要保證每個數(shù)據(jù)包都完整到達(dá),允許一定的丟包率,這個時候TCP的可靠特性反而成為了累贅;精簡的UDP更高的效率是更加適合的選擇

可以進(jìn)行廣播;UDP并不是面向連接的,所以可以同時對多個進(jìn)程進(jìn)行發(fā)送報文

UDP適用場景

UDP適用于對傳輸模型需要應(yīng)用層高度自定義、允許出現(xiàn)丟包、需要高效率的場景、需要廣播;例如

視屏直播

DNS

RIP路由選擇協(xié)議

/ 其他補(bǔ)充 /

分塊傳輸

我們可以發(fā)現(xiàn),運輸層在傳輸數(shù)據(jù)的時候,并不是把整個數(shù)據(jù)包加個首部直接發(fā)送過去,而是會拆分成多個報文分開發(fā)送;那他這樣做原因是什么? 有讀者可能會想到:數(shù)據(jù)鏈路層限制了數(shù)據(jù)長度只能有1460。那數(shù)據(jù)鏈路層為什么要這么限制?他的本質(zhì)原因就是:網(wǎng)絡(luò)是不穩(wěn)定的。如果報文太長,那么極有可能在傳輸一般的時候突然中斷了,這個時候就要整個數(shù)據(jù)重傳,效率就降低了。把數(shù)據(jù)拆分成多個數(shù)據(jù)報,那么當(dāng)某個數(shù)據(jù)報丟失,只需要重傳該數(shù)據(jù)報即可。 那是不是拆分得越細(xì)越好?報文中數(shù)據(jù)字段長度太低,會使得首部的占比太大,這樣首部就會成為網(wǎng)絡(luò)傳輸最大的負(fù)擔(dān)了。例如1000字節(jié),每個報文首部是40字節(jié),如果拆分成10個報文,那么只需要傳輸400字節(jié)的首部;而如果拆分成1000個,那么需要傳輸40000字節(jié)的首部,效率就極大地降低了。

路由轉(zhuǎn)換

先看下圖:

a0c01742-0272-11ed-ba43-dac502259ad0.png

正常情況下,主機(jī)A的數(shù)據(jù)包可以又 1-3-6-7路徑進(jìn)行傳送

如果路由3壞掉了,那么可以從 1-4-6-7進(jìn)行傳送

如果4也壞掉了,那么只能從2-5-6-7傳送

如果5壞掉了,那么就中斷線路了

可以看出來,使用路由轉(zhuǎn)發(fā)的好處是:提高網(wǎng)絡(luò)的容錯率,本質(zhì)原因依舊是網(wǎng)絡(luò)是不穩(wěn)定的 。即使壞掉幾個路由器,網(wǎng)絡(luò)依舊暢通。但是如果壞掉路由器6那就直接導(dǎo)致主機(jī)A和主機(jī)B無法通信,所以要避免這種核心路由器的存在。 使用路由的好處還有:分流。如果一條線路太擁堵,可以從別的路線進(jìn)行傳輸,提高效率。

粘包與拆包

在面向字節(jié)流那一小節(jié)講過,TCP不懂這些數(shù)據(jù)流的意義,他只知道從應(yīng)用層拿到數(shù)據(jù)流,切割成一份份報文,然后發(fā)送給目標(biāo)對象。而如果應(yīng)用層傳輸下來的是兩個數(shù)據(jù)包,那么極有可能出現(xiàn)這種情況:

a0cf138c-0272-11ed-ba43-dac502259ad0.png

應(yīng)用層需要向目標(biāo)進(jìn)程發(fā)送兩份數(shù)據(jù),一份音頻,一份文本

TCP只知道接收到一個流,并把流拆分成4段進(jìn)行發(fā)送

中間第二個報文的數(shù)據(jù)就出現(xiàn)兩個文件的數(shù)據(jù)混在一起,這就是粘包

目標(biāo)進(jìn)程應(yīng)用層在接收到數(shù)據(jù)之后,需要把這些數(shù)據(jù)拆分成正確的兩個文件,就是拆包

粘包與拆包都是應(yīng)用層需要解決的問題,可以在每個文件的最后附加上一些特殊的字節(jié),如換行符;或者控制每個報文只包含一個文件的數(shù)據(jù),不足的用0補(bǔ)充等等。

惡意攻擊

TCP的面向連接特點可能會被惡意的人利用,對服務(wù)器進(jìn)行攻擊。 前面我們知道,當(dāng)我們向一個主機(jī)發(fā)送syn包請求創(chuàng)建連接時,服務(wù)器會為我們創(chuàng)建緩沖區(qū)等,然后向我們返回syn+ack報文;如果我們偽造IP和端口,向一個服務(wù)器進(jìn)行海量的請求,會使得服務(wù)器創(chuàng)建了大量的創(chuàng)建一半的TCP連接,使得其無法正常響應(yīng)用戶的請求,導(dǎo)致服務(wù)器癱瘓。 解決的方法可以有限制IP的創(chuàng)建連接數(shù)、讓創(chuàng)建一半的tcp連接在更短的時間內(nèi)自行關(guān)閉、延緩接收緩沖區(qū)內(nèi)存的分配等等。

長連接

我們向服務(wù)器的每一次請求都需要創(chuàng)建一個TCP連接,服務(wù)器返回數(shù)據(jù)之后就會關(guān)閉連接;如果在短時間內(nèi)有大量的請求,那么頻繁創(chuàng)建TCP連接關(guān)閉TCP連接是一個很浪費資源的行為。所以我們可以讓TCP連接不要關(guān)閉,在這個期間進(jìn)行請求,提高效率。 需要注意長連接維持時間、創(chuàng)建條件等,避免被惡意利用創(chuàng)建大量的長連接,消耗殆盡服務(wù)器的資源。 / 最后 / 以前學(xué)習(xí)的時候覺得這些東西好像沒什么卵用,貌似就是用來考試的。事實上,在沒應(yīng)用到的時候,對這些知識很難有更深層次的認(rèn)知,例如現(xiàn)在我看上面的總結(jié),很多只是表面上的認(rèn)知,不知道他背后代表的真正含義。 但當(dāng)我學(xué)習(xí)的更加廣泛、深入,會對這些知識有越來越深刻的認(rèn)識。有那么幾個瞬間覺得:哦原來那個東西是這樣運用,那個東西是這樣的啊,原來學(xué)了是真的有用。 現(xiàn)在可能學(xué)了之后沒有什么感覺,但是當(dāng)用到或者學(xué)到相關(guān)的應(yīng)用時,會有一個頓悟感,會瞬間收獲很多。

審核編輯 :李倩

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • TCP
    TCP
    +關(guān)注

    關(guān)注

    8

    文章

    1372

    瀏覽量

    79142
  • 物理層
    +關(guān)注

    關(guān)注

    1

    文章

    152

    瀏覽量

    34415

原文標(biāo)題:TCP,這篇總結(jié)的不錯

文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    pcb設(shè)計時注意事項

    前期確定的外圍結(jié)構(gòu)和接口布局,將元器件合理的排布 到PCB板框范圍內(nèi)。 布線 ? 根據(jù)根據(jù)和整體網(wǎng)表,確定信號分層和電源分層。 ? 根據(jù)網(wǎng)
    發(fā)表于 12-26 16:51

    了解這8要素,峟思教你如何選對應(yīng)變

    ?在工程領(lǐng)域中,應(yīng)變的正確選用至關(guān)重要。很多人不知道如何選擇合適的應(yīng)變,以下是峟思給大家介紹選擇應(yīng)變要了解的八大要素,教你正確選用應(yīng)變。一、測量對象首先要明確應(yīng)變
    的頭像 發(fā)表于 12-02 12:19 ?152次閱讀
    了解這8要素,峟思教你如何選對應(yīng)變<b class='flag-5'>計</b>

    滲壓和水位之間有什么區(qū)別?

    問題,南京峟思今天就來給大家簡單的介紹一下:滲壓和水位之間有什么區(qū)別?1.滲壓滲壓是一種能夠測量水工結(jié)構(gòu)物或其它混凝土
    的頭像 發(fā)表于 11-26 15:18 ?204次閱讀
    滲壓<b class='flag-5'>計</b>和水位<b class='flag-5'>計</b>之間有什么區(qū)別?

    多點位移安裝與埋設(shè)的基本步驟

    多點位移作為一種重要的監(jiān)測工具,廣泛應(yīng)用于壩體廊道、隧道、山體邊坡、土壩、路堤、基坑等工程結(jié)構(gòu)的位移測量。正確的安裝與埋設(shè)是保證其測量準(zhǔn)確性和可靠性的關(guān)鍵。以下是多點位移安裝與埋設(shè)的基本步驟,供
    的頭像 發(fā)表于 11-13 12:59 ?509次閱讀
    多點位移<b class='flag-5'>計</b>安裝與埋設(shè)的基本步驟

    振弦式表面應(yīng)變具有哪些功能?

    ?  在現(xiàn)代工程領(lǐng)域中,振弦式表面式應(yīng)變作為一種至關(guān)重要的測量工具,發(fā)揮著舉足輕重的作用。它是一種專門用于測量結(jié)構(gòu)表面應(yīng)變的傳感器,通過精確的測量和數(shù)據(jù)反饋,為工程結(jié)構(gòu)的安全性評估、設(shè)計優(yōu)化以及
    發(fā)表于 10-28 13:53

    以太網(wǎng)結(jié)構(gòu)是怎樣的

    以太網(wǎng)幀(Ethernet Frame)是以太網(wǎng)(Ethernet)協(xié)議用于在局域網(wǎng)(LAN)中傳輸數(shù)據(jù)的基本單位。理解以太網(wǎng)幀的結(jié)構(gòu)對于掌
    的頭像 發(fā)表于 10-08 10:00 ?1230次閱讀

    電位原理傳感器# 電位# 傳感器

    電位
    hbhxcg7865
    發(fā)布于 :2024年10月08日 09:58:04

    KPM12電位# 電位

    電位
    hbhxcg7865
    發(fā)布于 :2024年08月01日 13:55:14

    遞歸神經(jīng)網(wǎng)絡(luò)和循環(huán)神經(jīng)網(wǎng)絡(luò)的模型結(jié)構(gòu)

    遞歸神經(jīng)網(wǎng)絡(luò)是一種旨在處理分層結(jié)構(gòu)的神經(jīng)網(wǎng)絡(luò),使其特別適合涉及樹狀或嵌套數(shù)據(jù)的任務(wù)。這些網(wǎng)絡(luò)明確地模擬了層次結(jié)構(gòu)中的關(guān)系和依賴關(guān)系,例如語言中的句法結(jié)構(gòu)或圖像中的層次表示。它使用遞歸操
    的頭像 發(fā)表于 07-10 17:21 ?688次閱讀
    遞歸神經(jīng)網(wǎng)絡(luò)和循環(huán)神經(jīng)網(wǎng)絡(luò)的模型<b class='flag-5'>結(jié)構(gòu)</b>

    靜電和驗電器的區(qū)別

    靜電和驗電器在物理學(xué)中都是用于電荷測量的工具,但它們在結(jié)構(gòu)、工作原理、作用等方面存在顯著的區(qū)別。
    的頭像 發(fā)表于 05-20 17:15 ?3861次閱讀

    功率的工作原理和基本結(jié)構(gòu)

    在電力電子、通信、科研等領(lǐng)域,功率作為一種測量電功率的儀器,發(fā)揮著至關(guān)重要的作用。它能夠準(zhǔn)確測量電路中的功率值,為設(shè)備的性能評估、優(yōu)化設(shè)計以及故障排查提供重要數(shù)據(jù)支持。本文將詳細(xì)介紹功率的定義、工作原理和基本結(jié)構(gòu),并結(jié)合實際
    的頭像 發(fā)表于 05-15 16:58 ?2027次閱讀

    光功率和光功率分布計有啥區(qū)別

    光功率和光功率分布都是光纖通信和測試領(lǐng)域中用于測量光功率的儀器,但它們在測量目的、原理、結(jié)構(gòu)和應(yīng)用方面存在一些重要的區(qū)別。
    的頭像 發(fā)表于 05-15 16:57 ?655次閱讀

    以太網(wǎng)怎么連接 以太網(wǎng)組網(wǎng)結(jié)構(gòu)分析

    以太網(wǎng)的組網(wǎng)結(jié)構(gòu)涉及多個層面和組件。首先,從網(wǎng)絡(luò)結(jié)構(gòu)的角度來看,以太網(wǎng)分為物理層、數(shù)據(jù)鏈路層和高層用戶層。其中,物理層采用特定的通信媒體,如50Ω基帶同軸電纜,實現(xiàn)數(shù)據(jù)的傳輸。數(shù)據(jù)鏈路
    的頭像 發(fā)表于 03-08 17:19 ?3411次閱讀
    以太<b class='flag-5'>網(wǎng)</b>怎么連接 以太<b class='flag-5'>網(wǎng)</b>組網(wǎng)<b class='flag-5'>結(jié)構(gòu)</b>分析

    計算機(jī)網(wǎng)絡(luò)為什么要分層

    因為如果兩臺計算機(jī)能夠相互通信的話,實際實現(xiàn)起來是非常困難操作的。我們分層的目的就是為了將困難的問題簡單化,并且如果我們分層了,我們在使用的時候就可以僅僅關(guān)注我們需要關(guān)注的層次,而不用理會其他層
    發(fā)表于 02-03 17:12 ?2367次閱讀
    計算機(jī)網(wǎng)絡(luò)為什么要<b class='flag-5'>分層</b>次

    以太網(wǎng)是什么拓?fù)?b class='flag-5'>結(jié)構(gòu) 以太網(wǎng)是星形還是總線型

    高速、可靠的局域網(wǎng)通信標(biāo)準(zhǔn)。以太網(wǎng)的拓?fù)?b class='flag-5'>結(jié)構(gòu)既可以是星形結(jié)構(gòu),也可以是總線型結(jié)構(gòu),具體的拓?fù)?b class='flag-5'>結(jié)構(gòu)取決于網(wǎng)絡(luò)設(shè)備的布局和配置。 首先,我們來探
    的頭像 發(fā)表于 01-18 11:01 ?2923次閱讀