摘要:這時候超過定時器設定的時間就會再次發送丟包的數據直到對端響應,所以需要每次都備份發送的數據。
UDP 面向報文
UDP 是一個面向報文(報文可以理解為一段段的數據)的協議。意思就是 UDP 只是報文的搬運工,不會對報文進行任何拆分和拼接操作。
具體來說
在發送端,應用層將數據傳遞給傳輸層的 UDP 協議,UDP 只會給數據增加一個 UDP 頭標識下是 UDP 協議,然后就傳遞給網絡層了
在接收端,網絡層將數據傳遞給傳輸層,UDP 只去除 IP 報文頭就傳遞給應用層,不會任何拼接操作
不可靠性UDP 是無連接的,也就是說通信不需要建立和斷開連接。
UDP 也是不可靠的。協議收到什么數據就傳遞什么數據,并且也不會備份數據,對方能不能收到是不關心的
UDP 沒有擁塞控制,一直會以恒定的速度發送數據。即使網絡條件不好,也不會對發送速率進行調整。這樣實現的弊端就是在網絡條件不好的情況下可能會導致丟包,但是優點也很明顯,在某些實時性要求高的場景(比如電話會議)就需要使用 UDP 而不是 TCP。
高效因為 UDP 沒有 TCP 那么復雜,需要保證數據不丟失且有序到達。所以 UDP 的頭部開銷小,只有八字節,相比 TCP 的至少二十字節要少得多,在傳輸數據報文時是很高效的。
頭部包含了以下幾個數據
兩個十六位的端口號,分別為源端口(可選字段)和目標端口
整個數據報文的長度
整個數據報文的檢驗和(IPv4 可選 字段),該字段用于發現頭部信息和數據中的錯誤
傳輸方式UDP 不止支持一對一的傳輸方式,同樣支持一對多,多對多,多對一的方式,也就是說 UDP 提供了單播,多播,廣播的功能。
TCP 頭部TCP 頭部比 UDP 頭部復雜的多
對于 TCP 頭部來說,以下幾個字段是很重要的
Sequence number,這個序號保證了 TCP 傳輸的報文都是有序的,對端可以通過序號順序的拼接報文
Acknowledgement Number,這個序號表示數據接收端期望接收的下一個字節的編號是多少,同時也表示上一個序號的數據已經收到
Window Size,窗口大小,表示還能接收多少字節的數據,用于流量控制
標識符
URG=1:該字段為一表示本數據報的數據部分包含緊急信息,是一個高優先級數據報文,此時緊急指針有效。緊急數據一定位于當前數據包數據部分的最前面,緊急指針標明了緊急數據的尾部。
ACK=1:該字段為一表示確認號字段有效。此外,TCP 還規定在連接建立后傳送的所有報文段都必須把 ACK 置為一。
PSH=1:該字段為一表示接收端應該立即將數據 push 給應用層,而不是等到緩沖區滿后再提交。
RST=1:該字段為一表示當前 TCP 連接出現嚴重問題,可能需要重新建立 TCP 連接,也可以用于拒絕非法的報文段和拒絕連接請求。
SYN=1:當SYN=1,ACK=0時,表示當前報文段是一個連接請求報文。當SYN=1,ACK=1時,表示當前報文段是一個同意建立連接的應答報文。
FIN=1:該字段為一表示此報文段是一個釋放連接的請求報文。
狀態機HTTP 是無連接的,所以作為下層的 TCP 協議也是無連接的,雖然看似 TCP 將兩端連接了起來,但是其實只是兩端共同維護了一個狀態
TCP 的狀態機是很復雜的,并且與建立斷開連接時的握手息息相關,接下來就來詳細描述下兩種握手。
在這之前需要了解一個重要的性能指標 RTT。該指標表示發送端發送數據到接收到對端數據所需的往返時間。
建立連接三次握手在 TCP 協議中,主動發起請求的一端為客戶端,被動連接的一端稱為服務端。不管是客戶端還是服務端,TCP 連接建立完后都能發送和接收數據,所以 TCP 也是一個全雙工的協議。
起初,兩端都為 CLOSED 狀態。在通信開始前,雙方都會創建 TCB。 服務器創建完 TCB 后遍進入 LISTEN 狀態,此時開始等待客戶端發送數據。
第一次握手
客戶端向服務端發送連接請求報文段。該報文段中包含自身的數據通訊初始序號。請求發送后,客戶端便進入 SYN-SENT 狀態,x 表示客戶端的數據通信初始序號。
第二次握手
服務端收到連接請求報文段后,如果同意連接,則會發送一個應答,該應答中也會包含自身的數據通訊初始序號,發送完成后便進入 SYN-RECEIVED 狀態。
第三次握手
當客戶端收到連接同意的應答后,還要向服務端發送一個確認報文??蛻舳税l完這個報文段后便進入ESTABLISHED 狀態,服務端收到這個應答后也進入 ESTABLISHED 狀態,此時連接建立成功。
PS:第三次握手可以包含數據,通過 TCP 快速打開(TFO)技術。其實只要涉及到握手的協議,都可以使用類似 TFO 的方式,客戶端和服務端存儲相同 cookie,下次握手時發出 cookie 達到減少 RTT 的目的。
你是否有疑惑明明兩次握手就可以建立起連接,為什么還需要第三次應答?
因為這是為了防止失效的連接請求報文段被服務端接收,從而產生錯誤。
可以想象如下場景??蛻舳税l送了一個連接請求 A,但是因為網絡原因造成了超時,這時 TCP 會啟動超時重傳的機制再次發送一個連接請求 B。此時請求順利到達服務端,服務端應答完就建立了請求。如果連接請求 A 在兩端關閉后終于抵達了服務端,那么這時服務端會認為客戶端又需要建立 TCP 連接,從而應答了該請求并進入 ESTABLISHED 狀態。此時客戶端其實是 CLOSED 狀態,那么就會導致服務端一直等待,造成資源的浪費。
PS:在建立連接中,任意一端掉線,TCP 都會重發 SYN 包,一般會重試五次,在建立連接中可能會遇到 SYN FLOOD 攻擊。遇到這種情況你可以選擇調低重試次數或者干脆在不能處理的情況下拒絕請求。
斷開鏈接四次握手TCP 是全雙工的,在斷開連接時兩端都需要發送 FIN 和 ACK。
第一次握手
若客戶端 A 認為數據發送完成,則它需要向服務端 B 發送連接釋放請求。
第二次握手
B 收到連接釋放請求后,會告訴應用層要釋放 TCP 鏈接。然后會發送 ACK 包,并進入 CLOSE_WAIT 狀態,表示 A 到 B 的連接已經釋放,不接收 A 發的數據了。但是因為 TCP 連接時雙向的,所以 B 仍舊可以發送數據給 A。
第三次握手
B 如果此時還有沒發完的數據會繼續發送,完畢后會向 A 發送連接釋放請求,然后 B 便進入 LAST-ACK 狀態。
PS:通過延遲確認的技術(通常有時間限制,否則對方會誤認為需要重傳),可以將第二次和第三次握手合并,延遲 ACK 包的發送。
第四次握手
A 收到釋放請求后,向 B 發送確認應答,此時 A 進入 TIME-WAIT 狀態。該狀態會持續 2MSL(最大段生存期,指報文段在網絡中生存的時間,超時會被拋棄) 時間,若該時間段內沒有 B 的重發請求的話,就進入 CLOSED 狀態。當 B 收到確認應答后,也便進入 CLOSED 狀態。
為什么 A 要進入 TIME-WAIT 狀態,等待 2MSL 時間后才進入 CLOSED 狀態?
為了保證 B 能收到 A 的確認應答。若 A 發完確認應答后直接進入 CLOSED 狀態,如果確認應答因為網絡問題一直沒有到達,那么會造成 B 不能正常關閉。
ARQ 協議ARQ 協議也就是超時重傳機制。通過確認和超時機制保證了數據的正確送達,ARQ 協議包含停止等待 ARQ 和連續 ARQ
停止等待 ARQ正常傳輸過程
只要 A 向 B 發送一段報文,都要停止發送并啟動一個定時器,等待對端回應,在定時器時間內接收到對端應答就取消定時器并發送下一段報文。
報文丟失或出錯
在報文傳輸的過程中可能會出現丟包。這時候超過定時器設定的時間就會再次發送丟包的數據直到對端響應,所以需要每次都備份發送的數據。
即使報文正常的傳輸到對端,也可能出現在傳輸過程中報文出錯的問題。這時候對端會拋棄該報文并等待 A 端重傳。
PS:一般定時器設定的時間都會大于一個 RTT 的平均時間。
ACK 超時或丟失
對端傳輸的應答也可能出現丟失或超時的情況。那么超過定時器時間 A 端照樣會重傳報文。這時候 B 端收到相同序號的報文會丟棄該報文并重傳應答,直到 A 端發送下一個序號的報文。
在超時的情況下也可能出現應答很遲到達,這時 A 端會判斷該序號是否已經接收過,如果接收過只需要丟棄應答即可。
這個協議的缺點就是傳輸效率低,在良好的網絡環境下每次發送報文都得等待對端的 ACK 。
連續 ARQ在連續 ARQ 中,發送端擁有一個發送窗口,可以在沒有收到應答的情況下持續發送窗口內的數據,這樣相比停止等待 ARQ 協議來說減少了等待時間,提高了效率。
累計確認連續 ARQ 中,接收端會持續不斷收到報文。如果和停止等待 ARQ 中接收一個報文就發送一個應答一樣,就太浪費資源了。通過累計確認,可以在收到多個報文以后統一回復一個應答報文。報文中的 ACK 可以用來告訴發送端這個序號之前的數據已經全部接收到了,下次請發送這個序號 + 1的數據。
但是累計確認也有一個弊端。在連續接收報文時,可能會遇到接收到序號 5 的報文后,并未接到序號 6 的報文,然而序號 7 以后的報文已經接收。遇到這種情況時,ACK 只能回復 6,這樣會造成發送端重復發送數據,這種情況下可以通過 Sack 來解決,這個會在下文說到。
滑動窗口在上面小節中講到了發送窗口。在 TCP 中,兩端都維護著窗口:分別為發送端窗口和接收端窗口。
發送端窗口包含已發送但未收到應答的數據和可以發送但是未發送的數據。
發送端窗口是由接收窗口剩余大小決定的。接收方會把當前接收窗口的剩余大小寫入應答報文,發送端收到應答后根據該值和當前網絡擁塞情況設置發送窗口的大小,所以發送窗口的大小是不斷變化的。
當發送端接收到應答報文后,會隨之將窗口進行滑動
滑動窗口實現了流量控制。接收方通過報文告知發送方還可以發送多少數據,從而保證接收方能夠來得及接收數據。
Zero 窗口在發送報文的過程中,可能會遇到對端出現零窗口的情況。在該情況下,發送端會停止發送數據,并啟動 persistent timer 。該定時器會定時發送請求給對端,讓對端告知窗口大小。在重試次數超過一定次數后,可能會中斷 TCP 鏈接。
擁塞處理擁塞處理和流量控制不同,后者是作用于接收方,保證接收方來得及接受數據。而前者是作用于網絡,防止過多的數據擁塞網絡,避免出現網絡負載過大的情況。
擁塞處理包括了四個算法,分別為:慢開始,擁塞避免,快速重傳,快速恢復。
慢開始算法慢開始算法,顧名思義,就是在傳輸開始時將發送窗口慢慢指數級擴大,從而避免一開始就傳輸大量數據導致網絡擁塞。
慢開始算法步驟具體如下
連接初始設置擁塞窗口(Congestion Window) 為 1 MSS(一個分段的最大數據量)
每過一個 RTT 就將窗口大小乘二
指數級增長肯定不能沒有限制的,所以有一個閾值限制,當窗口大小大于閾值時就會啟動擁塞避免算法。
擁塞避免算法擁塞避免算法相比簡單點,每過一個 RTT 窗口大小只加一,這樣能夠避免指數級增長導致網絡擁塞,慢慢將大小調整到最佳值。
在傳輸過程中可能定時器超時的情況,這時候 TCP 會認為網絡擁塞了,會馬上進行以下步驟:
將閾值設為當前擁塞窗口的一半
將擁塞窗口設為 1 MSS
啟動擁塞避免算法
快速重傳快速重傳一般和快恢復一起出現。一旦接收端收到的報文出現失序的情況,接收端只會回復最后一個順序正確的報文序號(沒有 Sack 的情況下)。如果收到三個重復的 ACK,無需等待定時器超時再重發而是啟動快速重傳。具體算法分為兩種:
TCP Taho 實現如下
將閾值設為當前擁塞窗口的一半
將擁塞窗口設為 1 MSS
重新開始慢開始算法
TCP Reno 實現如下
擁塞窗口減半
將閾值設為當前擁塞窗口
進入快恢復階段(重發對端需要的包,一旦收到一個新的 ACK 答復就退出該階段)
使用擁塞避免算法
TCP New Ren 改進后的快恢復TCP New Reno 算法改進了之前 TCP Reno 算法的缺陷。在之前,快恢復中只要收到一個新的 ACK 包,就會退出快恢復。
在 TCP New Reno 中,TCP 發送方先記下三個重復 ACK 的分段的最大序號。
假如我有一個分段數據是 1 ~ 10 這十個序號的報文,其中丟失了序號為 3 和 7 的報文,那么該分段的最大序號就是 10。發送端只會收到 ACK 序號為 3 的應答。這時候重發序號為 3 的報文,接收方順利接收并會發送 ACK 序號為 7 的應答。這時候 TCP 知道對端是有多個包未收到,會繼續發送序號為 7 的報文,接收方順利接收并會發送 ACK 序號為 11 的應答,這時發送端認為這個分段接收端已經順利接收,接下來會退出快恢復階段。
HTTPHTTP 協議是個無狀態協議,不會保存狀態。
Post 和 Get 的區別先引入副作用和冪等的概念。
副作用指對服務器上的資源做改變,搜索是無副作用的,注冊是副作用的。
冪等指發送 M 和 N 次請求(兩者不相同且都大于 1),服務器上資源的狀態一致,比如注冊 10 個和 11 個帳號是不冪等的,對文章進行更改 10 次和 11 次是冪等的。
在規范的應用場景上說,Get 多用于無副作用,冪等的場景,例如搜索關鍵字。Post 多用于副作用,不冪等的場景,例如注冊。
在技術上說:
Get 請求能緩存,Post 不能
Post 相對 Get 安全一點點,因為Get 請求都包含在 URL 里,且會被瀏覽器保存歷史紀錄,Post 不會,但是在抓包的情況下都是一樣的。
Post 可以通過 request body來傳輸比 Get 更多的數據,Get 沒有這個技術
URL有長度限制,會影響 Get 請求,但是這個長度限制是瀏覽器規定的,不是 RFC 規定的
Post 支持更多的編碼類型且不對數據類型限制
常見狀態碼2XX 成功
200 OK,表示從客戶端發來的請求在服務器端被正確處理
204 No content,表示請求成功,但響應報文不含實體的主體部分
205 Reset Content,表示請求成功,但響應報文不含實體的主體部分,但是與 204 響應不同在于要求請求方重置內容
206 Partial Content,進行范圍請求
3XX 重定向
301 moved permanently,永久性重定向,表示資源已被分配了新的 URL
302 found,臨時性重定向,表示資源臨時被分配了新的 URL
303 see other,表示資源存在著另一個 URL,應使用 GET 方法獲取資源
304 not modified,表示服務器允許訪問資源,但因發生請求未滿足條件的情況
307 temporary redirect,臨時重定向,和302含義類似,但是期望客戶端保持請求方法不變向新的地址發出請求
4XX 客戶端錯誤
400 bad request,請求報文存在語法錯誤
401 unauthorized,表示發送的請求需要有通過 HTTP 認證的認證信息
403 forbidden,表示對請求資源的訪問被服務器拒絕
404 not found,表示在服務器上沒有找到請求的資源
5XX 服務器錯誤
500 internal sever error,表示服務器端在執行請求時發生了錯誤
501 Not Implemented,表示服務器不支持當前請求所需要的某個功能
503 service unavailable,表明服務器暫時處于超負載或正在停機維護,無法處理請求
HTTP 首部通用字段 | 作用 |
---|---|
Cache-Control | 控制緩存的行為 |
Connection | 瀏覽器想要優先使用的連接類型,比如 keep-alive |
Date | 創建報文時間 |
Pragma | 報文指令 |
Via | 代理服務器相關信息 |
Transfer-Encoding | 傳輸編碼方式 |
Upgrade | 要求客戶端升級協議 |
Warning | 在內容中可能存在錯誤 |
請求字段 | 作用 |
---|---|
Accept | 能正確接收的媒體類型 |
Accept-Charset | 能正確接收的字符集 |
Accept-Encoding | 能正確接收的編碼格式列表 |
Accept-Language | 能正確接收的語言列表 |
Expect | 期待服務端的指定行為 |
From | 請求方郵箱地址 |
Host | 服務器的域名 |
If-Match | 兩端資源標記比較 |
If-Modified-Since | 本地資源未修改返回 304(比較時間) |
If-None-Match | 本地資源未修改返回 304(比較標記) |
User-Agent | 客戶端信息 |
Max-Forwards | 限制可被代理及網關轉發的次數 |
Proxy-Authorization | 向代理服務器發送驗證信息 |
Range | 請求某個內容的一部分 |
Referer | 表示瀏覽器所訪問的前一個頁面 |
TE | 傳輸編碼方式 |
響應字段 | 作用 |
---|---|
Accept-Ranges | 是否支持某些種類的范圍 |
Age | 資源在代理緩存中存在的時間 |
ETag | 資源標識 |
Location | 客戶端重定向到某個 URL |
Proxy-Authenticate | 向代理服務器發送驗證信息 |
Server | 服務器名字 |
WWW-Authenticate | 獲取資源需要的驗證信息 |
實體字段 | 作用 |
---|---|
Allow | 資源的正確請求方式 |
Content-Encoding | 內容的編碼格式 |
Content-Language | 內容使用的語言 |
Content-Length | request body 長度 |
Content-Location | 返回數據的備用地址 |
Content-MD5 | Base64加密格式的內容 MD5檢驗值 |
Content-Range | 內容的位置范圍 |
Content-Type | 內容的媒體類型 |
Expires | 內容的過期時間 |
Last_modified | 內容的最后修改時間 |
PS:緩存相關已在別的模塊中寫完,你可以 閱讀該小節
HTTPSHTTPS 還是通過了 HTTP 來傳輸信息,但是信息通過 TLS 協議進行了加密。
TLSTLS 協議位于傳輸層之上,應用層之下。首次進行 TLS 協議傳輸需要兩個 RTT ,接下來可以通過 Session Resumption 減少到一個 RTT。
在 TLS 中使用了兩種加密技術,分別為:對稱加密和非對稱加密。
對稱加密:
對稱加密就是兩邊擁有相同的秘鑰,兩邊都知道如何將密文加密解密。
非對稱加密:
有公鑰私鑰之分,公鑰所有人都可以知道,可以將數據用公鑰加密,但是將數據解密必須使用私鑰解密,私鑰只有分發公鑰的一方才知道。
TLS 握手過程如下圖:
客戶端發送一個隨機值,需要的協議和加密方式
服務端收到客戶端的隨機值,自己也產生一個隨機值,并根據客戶端需求的協議和加密方式來使用對應的方式,發送自己的證書(如果需要驗證客戶端證書需要說明)
客戶端收到服務端的證書并驗證是否有效,驗證通過會再生成一個隨機值,通過服務端證書的公鑰去加密這個隨機值并發送給服務端,如果服務端需要驗證客戶端證書的話會附帶證書
服務端收到加密過的隨機值并使用私鑰解密獲得第三個隨機值,這時候兩端都擁有了三個隨機值,可以通過這三個隨機值按照之前約定的加密方式生成密鑰,接下來的通信就可以通過該密鑰來加密解密
通過以上步驟可知,在 TLS 握手階段,兩端使用非對稱加密的方式來通信,但是因為非對稱加密損耗的性能比對稱加密大,所以在正式傳輸數據時,兩端使用對稱加密的方式通信。
PS:以上說明的都是 TLS 1.2 協議的握手情況,在 1.3 協議中,首次建立連接只需要一個 RTT,后面恢復連接不需要 RTT 了。
HTTP 2.0HTTP 2.0 相比于 HTTP 1.X,可以說是大幅度提高了 web 的性能。
在 HTTP 1.X 中,為了性能考慮,我們會引入雪碧圖、將小圖內聯、使用多個域名等等的方式。這一切都是因為瀏覽器限制了同一個域名下的請求數量,當頁面中需要請求很多資源的時候,隊頭阻塞(Head of line blocking)會導致在達到最大請求數量時,剩余的資源需要等待其他資源請求完成后才能發起請求。
你可以通過 該鏈接 感受下 HTTP 2.0 比 HTTP 1.X 到底快了多少。
在 HTTP 1.X 中,因為隊頭阻塞的原因,你會發現請求是這樣的
在 HTTP 2.0 中,因為引入了多路復用,你會發現請求是這樣的
二進制傳輸HTTP 2.0 中所有加強性能的核心點在于此。在之前的 HTTP 版本中,我們是通過文本的方式傳輸數據。在 HTTP 2.0 中引入了新的編碼機制,所有傳輸的數據都會被分割,并采用二進制格式編碼。
多路復用在 HTTP 2.0 中,有兩個非常重要的概念,分別是幀(frame)和流(stream)。
幀代表著最小的數據單位,每個幀會標識出該幀屬于哪個流,流也就是多個幀組成的數據流。
多路復用,就是在一個 TCP 連接中可以存在多條流。換句話說,也就是可以發送多個請求,對端可以通過幀中的標識知道屬于哪個請求。通過這個技術,可以避免 HTTP 舊版本中的隊頭阻塞問題,極大的提高傳輸性能。
Header 壓縮在 HTTP 1.X 中,我們使用文本的形式傳輸 header,在 header 攜帶 cookie 的情況下,可能每次都需要重復傳輸幾百到幾千的字節。
在 HTTP 2.0 中,使用了 HPACK 壓縮格式對傳輸的 header 進行編碼,減少了 header 的大小。并在兩端維護了索引表,用于記錄出現過的 header ,后面在傳輸過程中就可以傳輸已經記錄過的 header 的鍵名,對端收到數據后就可以通過鍵名找到對應的值。
服務端 Push在 HTTP 2.0 中,服務端可以在客戶端某個請求后,主動推送其他資源。
可以想象以下情況,某些資源客戶端是一定會請求的,這時就可以采取服務端 push 的技術,提前給客戶端推送必要的資源,這樣就可以相對減少一點延遲時間。當然在瀏覽器兼容的情況下你也可以使用 prefetch 。
QUIC這是一個谷歌出品的基于 UDP 實現的同為傳輸層的協議,目標很遠大,希望替代 TCP 協議。
該協議支持多路復用,雖然 HTTP 2.0 也支持多路復用,但是下層仍是 TCP,因為 TCP 的重傳機制,只要一個包丟失就得判斷丟失包并且重傳,導致發生隊頭阻塞的問題,但是 UDP 沒有這個機制
實現了自己的加密協議,通過類似 TCP 的 TFO 機制可以實現 0-RTT,當然 TLS 1.3 已經實現了 0-RTT 了
支持重傳和糾錯機制(向前恢復),在只丟失一個包的情況下不需要重傳,使用糾錯機制恢復丟失的包
糾錯機制:通過異或的方式,算出發出去的數據的異或值并多帶帶發出一個包,服務端在發現有一個包丟失的情況下,通過其他數據包和異或值包算出丟失包
在丟失兩個包或以上的情況就使用重傳機制,因為算不出來了
DNSDNS 的作用就是通過域名查詢到具體的 IP。
因為 IP 存在數字和英文的組合(IPv6),很不利于人類記憶,所以就出現了域名。你可以把域名看成是某個 IP 的別名,DNS 就是去查詢這個別名的真正名稱是什么。
在 TCP 握手之前就已經進行了 DNS 查詢,這個查詢是操作系統自己做的。當你在瀏覽器中想訪問 www.google.com 時,會進行一下操作:
操作系統會首先在本地緩存中查詢
沒有的話會去系統配置的 DNS 服務器中查詢
如果這時候還沒得話,會直接去 DNS 根服務器查詢,這一步查詢會找出負責 com 這個一級域名的服務器
然后去該服務器查詢 google 這個二級域名
接下來三級域名的查詢其實是我們配置的,你可以給 www 這個域名配置一個 IP,然后還可以給別的三級域名配置一個 IP
以上介紹的是 DNS 迭代查詢,還有種是遞歸查詢,區別就是前者是由客戶端去做請求,后者是由系統配置的 DNS 服務器做請求,得到結果后將數據返回給客戶端。
PS:DNS 是基于 UDP 做的查詢。
從輸入 URL 到頁面加載完成的過程這是一個很經典的面試題,在這題中可以將本文講得內容都串聯起來。
首先做 DNS 查詢,如果這一步做了智能 DNS 解析的話,會提供訪問速度最快的 IP 地址回來
接下來是 TCP 握手,應用層會下發數據給傳輸層,這里 TCP 協議會指明兩端的端口號,然后下發給網絡層。網絡層中的 IP 協議會確定 IP 地址,并且指示了數據傳輸中如何跳轉路由器。然后包會再被封裝到數據鏈路層的數據幀結構中,最后就是物理層面的傳輸了
TCP 握手結束后會進行 TLS 握手,然后就開始正式的傳輸數據
數據在進入服務端之前,可能還會先經過負責負載均衡的服務器,它的作用就是將請求合理的分發到多臺服務器上,這時假設服務端會響應一個 HTML 文件
首先瀏覽器會判斷狀態碼是什么,如果是 200 那就繼續解析,如果 400 或 500 的話就會報錯,如果 300 的話會進行重定向,這里會有個重定向計數器,避免過多次的重定向,超過次數也會報錯
瀏覽器開始解析文件,如果是 gzip 格式的話會先解壓一下,然后通過文件的編碼格式知道該如何去解碼文件
文件解碼成功后會正式開始渲染流程,先會根據 HTML 構建 DOM 樹,有 CSS 的話會去構建 CSSOM 樹。如果遇到 script 標簽的話,會判斷是否存在 async 或者 defer ,前者會并行進行下載并執行 JS,后者會先下載文件,然后等待 HTML 解析完成后順序執行,如果以上都沒有,就會阻塞住渲染流程直到 JS 執行完畢。遇到文件下載的會去下載文件,這里如果使用 HTTP 2.0 協議的話會極大的提高多圖的下載效率。
初始的 HTML 被完全加載和解析后會觸發 DOMContentLoaded 事件
CSSOM 樹和 DOM 樹構建完成后會開始生成 Render 樹,這一步就是確定頁面元素的布局、樣式等等諸多方面的東西
在生成 Render 樹的過程中,瀏覽器就開始調用 GPU 繪制,合成圖層,將內容顯示在屏幕上了
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108888.html
摘要:這時候超過定時器設定的時間就會再次發送丟包的數據直到對端響應,所以需要每次都備份發送的數據。 UDP 面向報文 UDP 是一個面向報文(報文可以理解為一段段的數據)的協議。意思就是 UDP 只是報文的搬運工,不會對報文進行任何拆分和拼接操作。 具體來說 在發送端,應用層將數據傳遞給傳輸層的 UDP 協議,UDP 只會給數據增加一個 UDP 頭標識下是 UDP 協議,然后就傳遞給網絡層...
摘要:代碼實現代碼實現接下來思考一個熔斷器如何實現。同時熔斷器的狀態也需要依靠指標統計來實現可觀測性,我們實現任何系統第一步需要考慮就是可觀測性,不然系統就是一個黑盒。可能是,熔斷器需要實時收集此數據。熔斷方法,自動上報執行結果自動擋。。。為什么需要熔斷微服務集群中,每個應用基本都會依賴一定數量的外部服務。有可能隨時都會遇到網絡連接緩慢,超時,依賴服務過載,服務不可用的情況,在高并發場景下如果此時...
摘要:端口,協議,域名,有一者不同就會出現跨域的問題。解決跨域的方式怎樣解決跨域所謂的解決跨域問題就是前端在合適的時期動態添加一個標簽,請求后端給的接口帶上一個回調函數。因為標簽不受瀏覽器同源策略的限制。 跨域 為什么會出現跨域? 因為瀏覽器有同源策略的限制,同源策略是瀏覽器最核心最基礎的安全策略。 端口,協議,域名,有一者不同就會出現跨域的問題。 解決跨域的方式 JSONP CORS...
摘要:決定了注冊的事件是捕獲事件還是冒泡事件。瀏覽器會自動進行通信,實現通信的關鍵是后端。該方式只能用于二級域名相同的情況下,比如和適用于該方式。中的中的和瀏覽器中的不相同。 事件機制 事件觸發三階段 事件觸發有三個階段 window 往事件觸發處傳播,遇到注冊的捕獲事件會觸發 傳播到事件觸發處時觸發注冊的事件 從事件觸發處往 window 傳播,遇到注冊的冒泡事件會觸發 事件觸發一般...
閱讀 1437·2021-11-25 09:43
閱讀 2580·2021-09-24 10:30
閱讀 3659·2021-09-06 15:02
閱讀 3593·2019-08-30 15:55
閱讀 3300·2019-08-30 15:53
閱讀 1693·2019-08-30 15:52
閱讀 2142·2019-08-30 14:21
閱讀 2010·2019-08-30 13:55