激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

電腦之家 - 專業(yè)計算機(jī)基礎(chǔ)知識與電腦技術(shù)學(xué)習(xí)網(wǎng)站
分類導(dǎo)航

路由器|交換機(jī)|網(wǎng)絡(luò)協(xié)議|網(wǎng)絡(luò)知識|

服務(wù)器之家 - 電腦之家 - 網(wǎng)絡(luò)技術(shù) - 請求數(shù)據(jù)包從發(fā)送到接收,都經(jīng)歷了什么?

請求數(shù)據(jù)包從發(fā)送到接收,都經(jīng)歷了什么?

2021-10-08 23:23SH的全棧筆記 網(wǎng)絡(luò)技術(shù)

這篇文章不會涉及到上面提到的什么各種狀態(tài)的變化,包內(nèi)的標(biāo)志位是什么,而是會更加關(guān)注于底層的東西,也就是上面那些發(fā)來發(fā)去的數(shù)據(jù)包是如何發(fā)送出去的。

請求數(shù)據(jù)包從發(fā)送到接收,都經(jīng)歷了什么?

之前講了「從輸入 URL 再到瀏覽器成功看到界面」中的域名是如何變成 IP 地址的,了解了 DNS 相關(guān)的東西。這篇文章就聊聊發(fā)生在 DNS 解析之后的操作——建立連接。也就是我們常說的三次握手

看到三次握手你可能會說,這不是面試都被問爛了的題嗎?

三次握手不就是:

  1. 服務(wù)器開始為 CLOSE 狀態(tài),然后監(jiān)聽某個端口,此時服務(wù)器會進(jìn)入 LISTEN 狀態(tài)
  2. 客戶端最初也是 CLOSE 狀態(tài),客戶端會向服務(wù)器發(fā)送一個帶 SYN 標(biāo)志位的數(shù)據(jù)包,主動發(fā)起連接。此時客戶端會變成 SYN-SENT 狀態(tài)
  3. 服務(wù)器接收到客戶端的數(shù)據(jù)包之后,通過標(biāo)志位判斷出了客戶端想要建立連接。然后返回一個 SYN 和 ACK ,此時服務(wù)器的狀態(tài)變?yōu)榱?SYN-RCVD
  4. 客戶端收到了服務(wù)器的 ACK 之后,會回一個 ACK 給服務(wù)器,回完這個 ACK 之后,服務(wù)器的狀態(tài)就變?yōu)榱?ESTABLISH
  5. 服務(wù)器收到了客戶端回復(fù)的 ACK 之后,服務(wù)器的狀態(tài)也變成了 ESTABLISH

這不就完了嗎?還有什么好聊的?

這篇文章不會涉及到上面提到的什么各種狀態(tài)的變化,包內(nèi)的標(biāo)志位是什么,而是會更加關(guān)注于底層的東西,也就是上面那些發(fā)來發(fā)去的數(shù)據(jù)包是如何發(fā)送出去的。

其實不僅僅是建立連接時的三次握手,像瀏覽器中調(diào)用的很多 HTTP 接口,都會和服務(wù)器進(jìn)行通信。

那這些個請求到底都是怎么發(fā)送給服務(wù)器的呢?

這還用問?不就是發(fā)個 HTTP 請求就過去了嗎?

當(dāng)然,這個答案可能是很多不了解網(wǎng)絡(luò)的人可能會說出的答案。

其實更具體、更準(zhǔn)確的說法是通過協(xié)議棧和網(wǎng)卡發(fā)送出去的。

其中,協(xié)議棧負(fù)責(zé)對數(shù)據(jù)進(jìn)行打包,打包完成之后就由網(wǎng)卡將數(shù)據(jù)轉(zhuǎn)換成電信號,通過光纖發(fā)送出去了。

請求數(shù)據(jù)包從發(fā)送到接收,都經(jīng)歷了什么?

網(wǎng)卡自不必說,用來和其他的計算機(jī)進(jìn)行通訊的硬件,我們常說的 MAC(Medium Access Control) 地址,其實就是網(wǎng)卡的編號,從其被生產(chǎn)出來的那一刻就被確定的一個唯一編號。MAC 地址長為 48 個比特,也就是 6 個字節(jié),用十六進(jìn)制進(jìn)行表示。

當(dāng)我們知道了和我們通信的 IP 地址之后,就可以委托操作系統(tǒng)中的協(xié)議棧將來來自應(yīng)用程序的數(shù)據(jù),打包成數(shù)據(jù)包然后發(fā)送出去。那協(xié)議棧,具體是啥呢?協(xié)議棧其實是一系列網(wǎng)絡(luò)協(xié)議的總和,例如:

  • TCP
  • UDP
  • IP

不同的應(yīng)用程序在進(jìn)行數(shù)據(jù)傳輸?shù)臅r候,可能會選擇不同的協(xié)議。例如我們使用的瀏覽器就是使用的 TCP 協(xié)議,而像之前講過的 DNS 解析就用的 UDP 協(xié)議。

那數(shù)據(jù)在協(xié)議棧中到底經(jīng)歷了什么?才變成了一個一個的數(shù)據(jù)包?

就拿我們向服務(wù)器發(fā)送一個 HTTP 請求作為例子,我們知道 HTTP 請求中有:

  • 請求行
  • 請求頭
  • 請求體

HTTP 是屬于應(yīng)用層的協(xié)議,而應(yīng)用層還有很多其他的協(xié)議,每個協(xié)議所涉及到的數(shù)據(jù)也都不同,協(xié)議棧要怎么去兼容不同協(xié)議之間的數(shù)據(jù)呢?

答案是不做兼容。對于協(xié)議棧來說,所有的數(shù)據(jù)都只不過是一堆二進(jìn)制序列。

請求數(shù)據(jù)包從發(fā)送到接收,都經(jīng)歷了什么?

那協(xié)議棧收到了這一堆二進(jìn)制序列之后是不是就直接交給網(wǎng)卡發(fā)送了呢?

我都這么問了,那顯然不是了...

其實協(xié)議棧在收到數(shù)據(jù)之后并不會馬上就會就發(fā)送出去,而是會先寫入位于內(nèi)存的 Buffer 中。那為啥不直接發(fā)出呢?

其實很簡單,假設(shè)你現(xiàn)在正在公交車的起始站,你覺得公交車會來一個人就立馬發(fā)車嗎?

顯然不是,它會等一段時間,有更多的乘客上車之后再發(fā)車。但是它又不能等太長的時間,不然后續(xù)站臺的乘客就會等的很久。

協(xié)議棧之所以不立即發(fā)出去,其實也是同樣的道理。其實這背后無非基礎(chǔ)兩種考慮:

  1. 數(shù)據(jù)的長度
  2. 等待的時間

應(yīng)用層的程序發(fā)送過來的數(shù)據(jù)可能長度都不太一樣,有的可能一個字節(jié)一個字節(jié)的發(fā), 有的可能一次性就傳入所有的數(shù)據(jù)。

如果收到數(shù)據(jù)就發(fā)送出去,會導(dǎo)致在網(wǎng)絡(luò)中傳輸著很多小包,而這會降低網(wǎng)絡(luò)傳輸?shù)男省?

請求數(shù)據(jù)包從發(fā)送到接收,都經(jīng)歷了什么?

所以,協(xié)議棧在收到數(shù)據(jù)之后會等待一段時間,等數(shù)據(jù)達(dá)到一定量之后,再執(zhí)行發(fā)送操作。

請求數(shù)據(jù)包從發(fā)送到接收,都經(jīng)歷了什么?

但是,協(xié)議棧又不能等的太久是吧?等太久了你讓正在電腦面前操作的用戶情何以堪,這種發(fā)送延遲會讓用戶體驗刷刷的往下掉。

但是吧,想做到對這兩者的平衡卻不是一件簡單的事。數(shù)據(jù)包太短,降低網(wǎng)絡(luò)傳輸效率,等待太長時間,又會造成發(fā)送延遲。所以協(xié)議棧索性就把控制權(quán)交給了應(yīng)用程序。

應(yīng)用程序可以自己控制到底采取哪種措施,例如我們常用的瀏覽器,因為和用戶實時的在進(jìn)行交互,用戶對整個頁面的響應(yīng)速度也相當(dāng)敏感,所以一般都會采用直接發(fā)送數(shù)據(jù)的方式,即使其數(shù)據(jù)并沒有達(dá)到「一定的量」

這一個「一定的量」到底是啥?

的確,上面都只說一定的量、一定的量,那這個量到底是多少?

要了解這個我們需要知道兩個參數(shù),分別是:

  1. MTU(Maximum Transmission Unit)最大傳輸單元
  2. MSS(Maximum Segment Size)最大分段大小

MTU 其實就代表了上面途中數(shù)據(jù)包的最大長度,一般來說是 1500 字節(jié)。而我們需要知道數(shù)據(jù)包是由以下部分組成的:

  1. 各種頭部信息
  2. 真實數(shù)據(jù)

而從 MTU 中減去各種頭部數(shù)據(jù)的大小,剩下的就是 MSS 了,也就是實際的數(shù)據(jù)。

請求數(shù)據(jù)包從發(fā)送到接收,都經(jīng)歷了什么?

知道了數(shù)據(jù)包的組成和 MTU、MSS 的概念之后,我們就可以繼續(xù)接下來的步驟了。某次發(fā)送的數(shù)據(jù),沒有超過 MSS 還好,就可以直接發(fā)送出去了。

那如果超過了 MSS 咋辦?例如我發(fā)這篇文章時所發(fā)請求的數(shù)據(jù)長度就可能超過 MSS 。

請求數(shù)據(jù)包從發(fā)送到接收,都經(jīng)歷了什么?

過長數(shù)據(jù)包拆分

此時就需要對數(shù)據(jù)進(jìn)行拆分,按照 MSS 的長度為單位進(jìn)行拆分,將拆出來的數(shù)據(jù)分別裝進(jìn)不同的數(shù)據(jù)包中。拆分好之后,就可以發(fā)送給目標(biāo)服務(wù)器了。

TCP 會確保通信的服務(wù)器能夠收到數(shù)據(jù)包。傳輸時對每個字節(jié)都進(jìn)行了編號,舉個例子,假設(shè)此次傳輸?shù)臄?shù)據(jù)是 1 - 1000 字節(jié),然后服務(wù)器回的 ACK 就會是 1001,這就代表沒有丟包。

這些發(fā)送過的包都會暫存在 Buffer 中,如果傳輸?shù)倪^程中出錯,則可以進(jìn)行重發(fā)的補(bǔ)償措施。這也是為什么在數(shù)據(jù)鏈路層(例如網(wǎng)卡、路由器、集線器)等等都沒有補(bǔ)償機(jī)制,它們一旦檢測到錯誤會直接將包丟棄。然后由傳輸層重發(fā)就好。

那要是網(wǎng)絡(luò)很擁堵,服務(wù)器一直沒有返回怎么辦?

在服務(wù)器端,我們?nèi)ズ推渌谌l(fā)進(jìn)行交互時,是不是都會設(shè)定一個超時的時間?如果不設(shè)置超時時間那難道一直在這等下去嗎?

TCP 也同理。客戶端在等待服務(wù)器響應(yīng)時,會有一個時間叫 ACK 等待時間,其實也是超時時間。

當(dāng)網(wǎng)絡(luò)發(fā)生擁堵時,其實你完全也可以把網(wǎng)絡(luò)擁堵理解成路上堵車。此時,ACK 的返回就會變慢。如果返回時間長到了讓客戶端認(rèn)為服務(wù)器沒有收到,就有可能會重發(fā)。

并且有可能剛剛重發(fā)完,ACK 就到了。雖然服務(wù)器端可以通過序號來對包進(jìn)行判重,不會造成錯誤,但是這種沒有意義的重復(fù)包,在本身網(wǎng)絡(luò)負(fù)擔(dān)已經(jīng)很重的情況下,你還往里懟重復(fù)的無用的數(shù)據(jù)包,這不是扯淡嗎?這明顯不行的。

那怎么避免上面的這個情況呢?答案很簡單,稍微延長一點 ACK等待時間,這樣一來就能一定程度上避免上述的問題。但是用屁股想想應(yīng)該也知道,這個時間肯定不是越長越好,再長用戶那又該等爆炸了。

除了網(wǎng)絡(luò)波動會影響到 ACK 的返回時間,通信的物理距離也是一個影響的因素。說白了就是這玩意兒不可能設(shè)置一個固定的時間。所以,實際上,這個等待時間是動態(tài)調(diào)整的,這次稍微返回慢了點,那我下次就稍微延長一點等待時間。返回 ACK 的速度如果很給力,那么就會相應(yīng)的減少等待。

上面的概念也有一個大家很熟悉的名字,叫——超時重傳。

我們來設(shè)想一個更加極端的情況,假設(shè)你們通信的網(wǎng)線被挖斷了,甚至機(jī)房起火了,這個時候無論你重發(fā)多少次都沒用。那 TCP 不就一直無限循環(huán)的把請求發(fā)下去了?

當(dāng)然 TCP 設(shè)計時也考慮到了這種情況,其在重傳幾次無效之后,就會強(qiáng)制中斷通信,并拋出錯誤給應(yīng)用程序。

問題又來了,客戶端在向服務(wù)器發(fā)送數(shù)據(jù)包之后,等待 ACK 的過程中,真的就只是等 ACK,其他的什么也不做嗎?

當(dāng)然不是,這樣極其的浪費資源,降低通信效率。發(fā)送完一個數(shù)據(jù)包之后,不用等待 ACK 的返回,會直接繼續(xù)發(fā)送下一個包,這就是滑動窗口。

但是這樣會有一個問題,應(yīng)用程序發(fā)送包發(fā)送的過于頻繁,導(dǎo)致服務(wù)器接收不過來了。

因為剛剛說過,應(yīng)用程序發(fā)送的時候,會將發(fā)送過的數(shù)據(jù)存儲在 buffer 中。而對于接收方也是一樣的,接收方收到消息之后,會將數(shù)據(jù)存儲在 Buffer 中,然后在 Buffer 中對收到的數(shù)據(jù)進(jìn)行重組,還原成最初的應(yīng)用程序發(fā)送的數(shù)據(jù)。

但是如果發(fā)送的數(shù)據(jù)太快,超過了重組的速度,緩沖區(qū)就會被填滿。而緩沖區(qū)一旦被填滿,后續(xù)的數(shù)據(jù)就無法再接收了,然后丟包就出現(xiàn)了。

那 TCP 是如何解決這個問題的呢?答案是 流量控制。為了防止傳輸方發(fā)送的過快直接造成丟包,繼而觸發(fā)上面的超時重傳機(jī)制,根據(jù)接收方的接受能力,來決定發(fā)送方的傳輸速度,這個機(jī)制就是流量控制。

該機(jī)制作用于接受方。在TCP報文頭部中會用一個16位的字段來表示窗口大小,非常重要的調(diào)優(yōu)參數(shù)。這個數(shù)字越大,則說明接收方的緩沖區(qū)越大,能夠接收更多的數(shù)據(jù)。接收方會在確認(rèn)應(yīng)答的時候,將自己的剩余窗口大小寫入,隨ACK一起發(fā)送給發(fā)送方。

請求數(shù)據(jù)包從發(fā)送到接收,都經(jīng)歷了什么?

TCP流量控制

如果發(fā)送方接收到的大小為0,那么此時就會停止發(fā)送數(shù)據(jù)。這樣會有一個問題,如果下一個應(yīng)答(也就是窗口大小不為0)在過程中丟了,那么發(fā)送方就會進(jìn)入死鎖,相互等待。所以發(fā)送方會定期的向接收方發(fā)送窗口探測的數(shù)據(jù)段。

好了,關(guān)于數(shù)據(jù)包的發(fā)送就介紹到這里。之后有機(jī)會再聊聊 TCP 的擁塞控制相關(guān)的東西。

原文鏈接:https://mp.weixin.qq.com/s/JYPhwwuBPPHH8GgJtoCyug

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91久久国产综合精品女同国语 | 久久久精品视频在线观看 | 国产精品久久久久久久久久三级 | 成人在线观看免费观看 | 久久久久二区 | 成人在线视频免费播放 | 日日艹夜夜艹 | 精品国产一区二区三区久久久蜜月 | 欧美日韩电影在线 | 九九热在线视频观看这里只有精品 | 极品xxxx欧美一区二区 | 91成人一区二区三区 | 国产一级淫 | 在线免费黄色网 | 久久国产精品99久久人人澡 | a级毛片免费观看在线播放 日本aaa一级片 | 日本在线播放一区二区三区 | 国产大片中文字幕在线观看 | 欧美自拍 | 最新中文字幕日本 | 干色视频 | 二区国产| 久草经典视频 | 狠狠干最新网址 | 国产成人强伦免费视频网站 | 午夜视频久久久 | 九草av| 日韩精品a在线观看 | 国产精品久久久久久久av三级 | 久久久久久久亚洲视频 | 久久99网 | 国产精品视频一区二区噜噜 | 久在线观看福利视频69 | 一级黄色电影网站 | 蝌蚪久久窝 | 中国毛片在线观看 | 久久久一区二区三区四区 | 色婷婷综合久久久中文一区二区 | 黄色片免费在线播放 | 成人不卡在线观看 | 久久精品操 |