一、大致流程
- 根據域名和 DNS 解析到服務器的IP地址 (DNS + CDN)
- 通過ARP協議獲得IP地址對應的物理機器的MAC地址
- 瀏覽器對服務器發起 TCP 3 次握手
- 建立 TCP 連接后發起 HTTP 請求報文
- 服務器響應 HTTP 請求,將響應報文返回給瀏覽器
- 短連接情況下,請求結束則通過 TCP 四次揮手關閉連接,長連接在沒有訪問服務器的若干時間后,進行連接的關閉
- 瀏覽器得到響應信息中的 HTML 代碼, 並請求 HTML 代碼中的資源(如js、css、圖片等)
- 瀏覽器對頁面進行渲染並呈現給用戶
二、深入分析
2.1 概括
在網絡協議方面,可以從三個方面深入分析
- DNS解析過程
- TCP連接過程(三次握手、四次揮手)
- HTTP請求響應過程
2.2 DNS協議
2.2.1 DNS解析過程
1.在瀏覽器中輸入www.qq.com域名,操作系統會先檢查瀏覽器會緩存是否有記錄, 然后再檢查自己本地的hosts文件是否有這個網址映射關系,如果有,就先調用這個IP地址映射,完成域名解析。
2.如果hosts里沒有這個域名的映射,則查找本地DNS解析器緩存,是否有這個網址映射關系,如果有,直接返回,完成域名解析。
3.如果hosts與本地DNS解析器緩存都沒有相應的網址映射關系,首先會找TCP/IP參數中設置的首選DNS服務器,在此我們叫它本地DNS服務器,此服務器收到查詢時,如果要查詢的域名,包含在本地配置區域資源中,則返回解析結果給客戶機,完成域名解析,此解析具有權威性。
4.如果要查詢的域名,不由本地DNS服務器區域解析,但該服務器已緩存了此網址映射關系,則調用這個IP地址映射,完成域名解析,此解析不具有權威性。
5.如果本地DNS服務器本地區域文件與緩存解析都失效,則根據本地DNS服務器的設置(是否設置轉發器)進行查詢,如果未用轉發模式,本地DNS就把請求發至 “根DNS服務器”,“根DNS服務器”收到請求后會判斷這個域名(.com)是誰來授權管理,並會返回一個負責該頂級域名服務器的一個IP。本地DNS服務器收到IP信息后,將會聯系負責.com域的這台服務器。這台負責.com域的服務器收到請求后,如果自己無法解析,它就會找一個管理.com域的下一級DNS服務器地址(qq.com)給本地DNS服務器。當本地DNS服務器收到這個地址后,就會找qq.com域服務器,重復上面的動作,進行查詢,直至找到www.qq.com主機。
6.如果用的是轉發模式,此DNS服務器就會把請求轉發至上一級DNS服務器,由上一級服務器進行解析,上一級服務器如果不能解析,或找根DNS或把轉請求轉至上上級,以此循環。不管是本地DNS服務器用是是轉發,還是根提示,最后都是把結果返回給本地DNS服務器,由此DNS服務器再返回給客戶機。
DNS主要是通過UDP通信,報文結構主要分為頭部Header、查詢部分Question、應答部分Answer/Authority/Addition。
2.2.2 DNS用的是TCP協議還是UDP協議
DNS占用53號端口,同時使用TCP和UDP協議。那么DNS在什么情況下使用這兩種協議?
DNS在區域傳輸的時候使用TCP協議,其他時候(如域名解析)使用UDP協議。
DNS區域傳輸的時候使用TCP協議:
1.輔域名服務器會定時(一般3小時)向主域名服務器進行查詢以便了解數據是否有變動。如有變動,會執行一次區域傳送,進行數據同步。區域傳送使用TCP而不是UDP,因為數據同步傳送的數據量比一個請求應答的數據量要多得多。
2.TCP是一種可靠連接,保證了數據的准確性。
域名解析時使用UDP協議:
客戶端向DNS服務器查詢域名,一般返回的內容都不超過512字節,用UDP傳輸即可。不用經過三次握手,這樣DNS服務器負載更低,響應更快。理論上說,客戶端也可以指定向DNS服務器查詢時用TCP,但事實上,很多DNS服務器進行配置的時候,僅支持UDP查詢包。
2.2.2 DNS為什么用TCP和UDP
DNS同時占用UDP和TCP端口53是公認的,這種單個應用協議同時使用兩種傳輸協議的情況在TCP/IP棧也算是個另類。但很少有人知道DNS分別在什么情況下使用這兩種協議。
先簡單介紹下TCP與UDP。
TCP是一種面向連接的協議,提供可靠的數據傳輸,一般服務質量要求比較高的情況,使用這個協議。UDP---用戶數據報協議,是一種無連接的傳輸層協議,提供面向事務的簡單不可靠
信息傳送服務。
TCP與UDP的區別:
UDP和TCP協議的主要區別是兩者在如何實現信息的可靠傳遞方面不同。TCP協議中包含了專門的傳遞保證機制,當數據接收方收到發送方傳來的信息時,會自動向發送方發出確認
消息;發送方只有在接收到該確認消息之后才繼續傳送其它信息,否則將一直等待直到收到確認信息為止。 與TCP不同,UDP協議並不提供數據傳送的保證機制。如果在從發送方到接收方的
傳遞過程中出現數據報的丟失,協議本身並不能做出任何檢測或提示。因此,通常人們把UDP協議稱為不可靠的傳輸協議。相對於TCP協議,UDP協議的另外一個不同之處在於如何接收突發
性的多個數據報。不同於TCP,UDP並不能確保數據的發送和接收順序。事實上,UDP協議的這種亂序性基本上很少出現,通常只會在網絡非常擁擠的情況下才有可能發生。
既然UDP是一種不可靠的網絡協議,那么還有什么使用價值或必要呢?其實不然,在有些情況下UDP協議可能會變得非常有用。因為UDP具有TCP所望塵莫及的速度優勢。雖然TCP協議中植入了各種安全保障功能,但是在實際執行的過程中會占用大量的系統開銷,無疑使速度受到嚴重的影響。反觀UDP由於排除了信息可靠傳遞機制,將安全和排序等功能移交給上層應用來完成,極大降低了執行時間,使速度得到了保證。
DNS在進行區域傳輸的時候使用TCP協議,其它時候則使用UDP協議;
DNS的規范規定了2種類型的DNS服務器,一個叫主DNS服務器,一個叫輔助DNS服務器。在一個區中主DNS服務器從自己本機的數據文件中讀取該區的DNS數據信息,而輔助DNS服務器則從區的主DNS服務器中讀取該區的DNS數據信息。當一個輔助DNS服務器啟動時,它需要與主DNS服務器通信,並加載數據信息,這就叫做區傳送(zone transfer)。
2.2.3 DNS為什么用TCP和UDP
首先了解以下TCP與UDP傳送字節的長度限制:
在以太網當中MTU是1500:
UDP 包的大小就應該是 1500 - IP頭(20) - UDP頭(8) = 1472(Bytes)
TCP 包的大小就應該是 1500 - IP頭(20) - TCP頭(20) = 1460 (Bytes)
在英特網當中標准MTU值為576字節:
UDP 包的大小就應該是 576 - IP頭(20) - UDP頭(8) = 548 (Bytes)
TCP 包的大小就應該是 576 - IP頭(20) - TCP頭(20) = 536 (Bytes)
區域傳送使用TCP,主要由以下兩點考慮:
1、TCP是一種可靠的連接,保證了數據的准確性。
2、輔域名服務器會定時(一般時3小時)向主域名服務器進行查詢以便了解數據是否有變動。如有變動,則會執行一次區域傳送,進行數據同步。區域傳送將使用TCP而不是UDP,因為數據同步傳送的數據量比一個請求和應答的數據量要多得多。
2.2.4 遞歸查詢與迭代查詢
一、主機向本地域名服務器的查詢一般都是采用遞歸查詢。
所謂遞歸查詢就是:如果主機所詢問的本地域名服務器不知道被查詢的域名的IP地址,那么本地域名服務器就以DNS客戶的身份,向其它根域名服務器繼續發出查詢請求報文(即替主機繼續查詢),而不是讓主機自己進行下一步查詢。因此,遞歸查詢返回的查詢結果或者是所要查詢的IP地址,或者是報錯,表示無法查詢到所需的IP地址。
二、本地域名服務器向根域名服務器的查詢的迭代查詢。
迭代查詢的特點:當根域名服務器收到本地域名服務器發出的迭代查詢請求報文時,要么給出所要查詢的IP地址,要么告訴本地服務器:“你下一步應當向哪一個域名服務器進行查詢”。然后讓本地服務器進行后續的查詢。根域名服務器通常是把自己知道的頂級域名服務器的IP地址告訴本地域名服務器,讓本地域名服務器再向頂級域名服務器查詢。頂級域名服務器在收到本地域名服務器的查詢請求后,要么給出所要查詢的IP地址,要么告訴本地服務器下一步應當向哪一個權限域名服務器進行查詢。最后,知道了所要解析的IP地址或報錯,然后把這個結果返回給發起查詢的主機
遞歸:客戶端只發一次請求,要求對方給出最終結果。
迭代:客戶端發出一次請求,對方如果沒有授權回答,它就會返回一個能解答這個查詢的其它名稱服務器列表,客戶端會再向返回的列表中發出請求,直到找到最終負責所查域名的名稱服務器,從它得到最終結果。
授權回答:向dns服務器查詢一個域名,剛好這個域名是本服務器負責,返回的結果就是授權回答。
從遞歸和迭代查詢可以看出:
客戶端-本地dns服務端:這部分屬於遞歸查詢。
本地dns服務端---外網:這部分屬於迭代查詢。
遞歸查詢時,返回的結果只有兩種:查詢成功或查詢失敗。
迭代查詢,又稱作重指引,返回的是最佳的查詢點或者主機地址。
2.2.5 DNS緩存
- 瀏覽器緩存 -瀏覽器會緩存 DNS 記錄一段時間。有趣的是,操作系統不會告訴瀏覽器每個 DNS 記錄的生存時間,因此瀏覽器將它們緩存一段固定的時間(不同瀏覽器不同,2 到 30 分鍾)。
- 操作系統緩存– 如果瀏覽器緩存不包含所需的記錄,瀏覽器會進行系統調用(Windows 中的 gethostbyname)。操作系統有自己的緩存(hosts文件和本地DNS緩存)。
- 路由器緩存- 請求繼續發送到您的路由器,路由器通常有自己的 DNS 緩存。
- ISP DNS 緩存– 下一個檢查的地方是緩存 ISP 的 DNS 服務器。自然而然地帶有緩存。
2.3 TCP 連接過程(3次握手 4次揮手)
- 三次握手
第一步:客戶端向服務端發送一份特殊的 TCP 報文,該報文並不包含應用層的數據,是一份特殊的報文,它的 TCP 首部中 SYN 字段值為 1 。除此之外,客戶端還會隨機生成一個初始序號,填在報文的「序號」字段,代表當前報文的序號是這個,並且我后續的分組會基於這個序號遞增。然后該報文將會經網絡層、鏈路層、物理層發送到服務端。
第二步:如果分組丟失了,那么客戶端會經過某個時間間隔再次嘗試發送。而如果分組准確的到達服務端了,服務端拆開 TCP 首部會看到,這是一個特殊的 SYN 握手報文,於是為此次連接分配緩存等資源。
接着服務端開始構建響應報文,SYN 是一個用於同步需要的字段,響應報文中依然會被置為 1,並且服務端也將隨機生成一個初始序號放置的響應報文的序號字段中。
最后,服務端還會為響應報文中的確認字段賦值,這個值就是客戶端發過來的那個序號值加一。
整體上的意思就是說,「我同意你的連接請求,我的初始序號為 xxx,你的初始序號我收到了,我等着你的下一個分組到來」
第三步:客戶端收到服務端的響應報文,於是分配客戶端 TCP 連接所必須的緩存等資源,於是連接已經建立。 - 四次揮手
第一步:客戶端構建一份特殊的 TCP 報文,該報文首部字段 FIN 被置為 1,然后發送該報文。
第二步:服務端收到該特殊的 FIN 報文,於是響應客戶端一個 ACK 報文,告訴客戶端,請求關閉的報文已經收到,我正在處理。
第三步:服務端發送一個 FIN 報文,告訴客戶端,我將要關閉連接了。
第四步:客戶端返回一個 ACK 響應報文,告訴服務端,我收到你剛才發的報文了,我已經確認,你可以關閉連接了。
當服務端收到客戶端發送的 ACK 響應報文時,將釋放服務端用於該 TCP 連接的所有資源,與此同時,客戶端也會定時等待一定時間后完全釋放自己用於該連接的相關資源。
三、參考文章
https://www.pianshen.com/article/712933935/
http://igoro.com/archive/what-really-happens-when-you-navigate-to-a-url/
https://www.cnblogs.com/qingdaofu/p/7399670.html
https://www.cnblogs.com/jiangzhaowei/p/9273854.html