自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

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

看到三次握手你可能會(huì)說(shuō),這不是面試都被問(wèn)爛了的題嗎?

三次握手不就是:

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

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

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

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

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

這還用問(wèn)?不就是發(fā)個(gè) HTTP 請(qǐng)求就過(guò)去了嗎?

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

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

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

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

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

  • TCP
  • UDP
  • IP

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

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

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

  • 請(qǐng)求行
  • 請(qǐng)求頭
  • 請(qǐng)求體

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

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

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

我都這么問(wèn)了,那顯然不是了...

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

其實(shí)很簡(jiǎn)單,假設(shè)你現(xiàn)在正在公交車(chē)的起始站,你覺(jué)得公交車(chē)會(huì)來(lái)一個(gè)人就立馬發(fā)車(chē)嗎?

顯然不是,它會(huì)等一段時(shí)間,有更多的乘客上車(chē)之后再發(fā)車(chē)。但是它又不能等太長(zhǎng)的時(shí)間,不然后續(xù)站臺(tái)的乘客就會(huì)等的很久。

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

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

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

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

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

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

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

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

這一個(gè)「一定的量」到底是啥?

的確,上面都只說(shuō)一定的量、一定的量,那這個(gè)量到底是多少?

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

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

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

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

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

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

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

過(guò)長(zhǎng)數(shù)據(jù)包拆分

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

因?yàn)閯倓傉f(shuō)過(guò),應(yīng)用程序發(fā)送的時(shí)候,會(huì)將發(fā)送過(guò)的數(shù)據(jù)存儲(chǔ)在 buffer 中。而對(duì)于接收方也是一樣的,接收方收到消息之后,會(huì)將數(shù)據(jù)存儲(chǔ)在 Buffer 中,然后在 Buffer 中對(duì)收到的數(shù)據(jù)進(jìn)行重組,還原成最初的應(yīng)用程序發(fā)送的數(shù)據(jù)。

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

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

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

TCP流量控制

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

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

 

責(zé)任編輯:姜華 來(lái)源: SH的全棧筆記
相關(guān)推薦

2023-09-06 07:51:19

KubernetesOperator

2017-11-14 16:38:05

智慧新城

2010-05-31 15:34:34

MySQL數(shù)據(jù)庫(kù)

2021-02-18 07:46:07

日志框架

2010-05-27 15:56:56

MySQL數(shù)據(jù)庫(kù)

2015-03-09 17:49:40

SDN

2010-06-30 12:37:04

SNMP服務(wù)器

2022-04-10 23:43:11

代碼發(fā)送郵件后端

2017-03-28 13:25:14

Linux網(wǎng)絡(luò)數(shù)據(jù)包

2021-05-17 05:07:41

Linux掃描儀Samba共享

2016-11-29 09:23:17

Spark集群部署

2017-04-07 09:30:49

Linux網(wǎng)絡(luò)數(shù)據(jù)包

2020-07-24 09:56:12

React開(kāi)發(fā)數(shù)據(jù)

2018-12-29 15:09:08

新零售無(wú)人超市智慧社區(qū)

2009-02-24 09:43:00

IP電話(huà)原理

2025-02-26 07:59:47

2017-02-24 08:30:50

網(wǎng)絡(luò)設(shè)備技術(shù)

2021-04-12 05:55:29

緩存數(shù)據(jù)Axios

2021-04-30 10:25:13

微軟Edge瀏覽器

2023-07-24 07:57:23

C++標(biāo)準(zhǔn)功能
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)