在瀏覽器地址欄輸入一個URL后回車,背后會進行哪些技術(shù)步驟?

作者:何偉鵬鏈接:https://www.zhihu.com/question/34873227/answer/70038032來源:知乎著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

計算機網(wǎng)絡(luò)龐大且復(fù)雜,很難一言或幾言以蔽之。因此,這里我們只考慮最一般的場景,所謂“一般”,就是...比如,沒有緩存,客戶機和服務(wù)器不在一個局域網(wǎng),輸入的是一個域名而不是IP地址,etc。我們采用自頂向下的方法,也是時間順序的方法,來解答這個問題。瀏覽器是C/S架構(gòu)中的客戶端,通過想服務(wù)器發(fā)送請求,獲取文件(html,js,css等),再通過瀏覽器引擎的解釋和渲染,將這些文件呈現(xiàn)成你現(xiàn)在看到的樣子。1、TCP/IP參考模型首先,我們不得不了解一下TCP/IP參考模型。如下圖所示,TCP/IP參考模型分為四層:應(yīng)用層、運輸層、網(wǎng)絡(luò)層和接口層。瀏覽器所完成的工作就屬于應(yīng)用層的范疇。


應(yīng)用層: 為用戶提供各種服務(wù),比如我們?yōu)g覽網(wǎng)頁時用到的HTTP,收發(fā)郵件時用的SMTP,登錄遠程主機用的SSH。
傳輸層:提供端到端的傳輸服務(wù)。更具體地講,提供進程到進程的傳輸服務(wù)。
網(wǎng)絡(luò)層:和傳輸層一樣,可以概括為提供端到端的傳輸服務(wù)。更具體地講,網(wǎng)絡(luò)層提供主機到主機的傳輸服務(wù)。
網(wǎng)絡(luò)接口層(鏈路層):為直接連接的設(shè)備提供傳輸服務(wù),將數(shù)據(jù)幀轉(zhuǎn)換為比特流,并將比特流轉(zhuǎn)換為物理電路的電壓高低信號。

2、往哪里發(fā)送請求?假設(shè)我么輸入的地址是zhihu.com

瀏覽器看到這個域名的時候,就好像我們想去一家從沒去過的餐廳吃飯,只知道名字是“黃大仙腸粉”但不知道具體地點在哪里。這個時候,我們打開地圖,搜索“黃大仙腸粉”后找到一個地址:衡山路110號,于是我們便知道該去哪了。域名就像是一個餐廳的名字,而IP地址相當于一個具體的地址。瀏覽器必須知道所請求服務(wù)器的IP地址,發(fā)出的請求才有目的地。DNS(Domain Name System)提供的服務(wù)就是將知乎的域名轉(zhuǎn)換成其服務(wù)器IP地址。DNS具有兩層含義:①一個由分層的DNS服務(wù)器實現(xiàn)的分布式數(shù)據(jù)庫;②一個允許主機查詢分布式數(shù)據(jù)庫的應(yīng)用層協(xié)議。有三種類型的DNS服務(wù)器:根DNS服務(wù)器、頂級DNS服務(wù)器和權(quán)威DNS服務(wù)器。這些服務(wù)器以下圖的層次結(jié)構(gòu)組織起來。除此之外,還有一類重要的DNS,稱為本地DNS服務(wù)器。嚴格來說本地DNS服務(wù)器并不屬于DNS服務(wù)器的層次結(jié)構(gòu),但它在整個查詢的過程中卻扮演著重要的角色。

除此之外,還有一類重要的DNS,稱為本地DNS服務(wù)器。嚴格來說本地DNS服務(wù)器并不屬于DNS服務(wù)器的層次結(jié)構(gòu),但它在整個查詢的過程中卻扮演著重要的角色。首先,瀏覽器所在的主機向本地DNS服務(wù)器發(fā)送一個含有知乎域名的DNS查詢報文。本地DNS服務(wù)器把查詢報文轉(zhuǎn)發(fā)到根DNS服務(wù)器,該根DNS服務(wù)器注意到其com后綴并向本地DNS服務(wù)器返回com的頂級域名服務(wù)器的IP地址。該本地DNS服務(wù)器再次向comDNS服務(wù)器發(fā)送查詢請求,comDNS服務(wù)器注意到其http://zhihu.com后綴并用負責該域名的權(quán)威DNS服務(wù)器的IP地址作為回應(yīng)。最后,本地域名服務(wù)器將含有http://zhihu.com的IP地址的響應(yīng)報文發(fā)送給客戶端主機。
這里的查詢過程是包含遞歸查詢和迭代查詢的,客戶端主機發(fā)送給本地服務(wù)器的查詢是遞歸查詢,而后面的三個查詢是迭代查詢。最高票 @郭無心 的答案中給出的遞歸查詢應(yīng)該是迭代查詢才對。2、封裝HTTP請求其實這里主要講HTTP報文的格式的??梢钥吹剑@個請求里面包含了請求的方法GET,請求的路徑“/”,請求的主機名,客戶機的類型以及一些其他的信息。GET / HTTP/1.1Host: zhihu.comUser-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64;Accept-Encoding: gzip, deflateConnection: Keep-Alive

前面辛辛苦苦通過DNS獲得的IP地址怎么沒有用到?HTTP請求報文里根本沒有這一個字段。繼續(xù)往下看。3、建立連接在應(yīng)用層和傳輸層之間,更準確地講是在瀏覽器進程和操作系統(tǒng)提供的TCP服務(wù)程序之間,有一個很重要的東西叫做套接字(Socket),如下圖所示。如果把一臺主機比作一座房子,把進程比作房子里面的房間,Socket相當于房間的門。不管是房間的人要出來還是外面的人要去到某一個房間,都必須先通過Socket這一道門。套接字的作用是實現(xiàn)傳輸層的多路復(fù)用和多路分解。在應(yīng)用層可以同時運行多個進程,每個進程都需要通過傳輸層來收發(fā)分組,而傳輸層的TCP進程只有一個,當TCP進程收到一個分組后,該怎么確定應(yīng)該轉(zhuǎn)發(fā)給哪個進程呢?答案是通過套接字,這就是多路分解。同樣的道理,多路復(fù)用就是進程將分組通過各自的套接字轉(zhuǎn)發(fā)給傳輸層。TCP套接字是由一個四元組(源IP地址、源端口號、目的IP地址和目的端口號)來標識的。

TCP是面向連接的,在實際發(fā)送數(shù)據(jù)之前,客戶端和服務(wù)器需要建立起一個TCP連接。這種TCP“連接”只是邏輯上的鏈接,因為其狀態(tài)完全保留在兩個端系統(tǒng)中,中間路由器對TCP連接毫不知情。


TCP是面向連接的,在實際發(fā)送數(shù)據(jù)之前,客戶端和服務(wù)器需要建立起一個TCP連接。這種TCP“連接”只是邏輯上的鏈接,因為其狀態(tài)完全保留在兩個端系統(tǒng)中,中間路由器對TCP連接毫不知情。TCP連接的建立過程如下圖所示。首先,TCP先發(fā)送一個創(chuàng)建連接的SYN請求,告訴服務(wù)器主機“我想和你創(chuàng)建一條TCP連接”。當服務(wù)器主機收到SYN請求后,如果其所請求的端口號正在等待連接,則會為這一條TCP連接分配資源,并發(fā)送一個SYNACK報文段作為應(yīng)答??蛻糁鳈C收到SYNACK報文段后,客戶機也為該連接分配資源。此時,連接已經(jīng)建立起來了??蛻糁鳈C還會向服務(wù)器主機發(fā)送另一個報文段,對允許連接的報文段進行確認。這就是有名的“三次握手”。
可以這樣簡單地認為,TCP連接創(chuàng)建成功的標志是:客戶機和服務(wù)器都創(chuàng)建了一個由源IP地址、源端口號、目的IP地址和目的端口號標志的Socket。4、發(fā)送請求請求在“三次握手”的第三次“握手”就發(fā)送出去了。TCP報文段的格式如下圖所示。

目的端口和源端口號是為了在多路復(fù)用和多路分解時選擇套接字時使用的。數(shù)據(jù)序號和確認序號是為了傳輸數(shù)據(jù)的完整性和順序而設(shè)置的。用戶數(shù)據(jù)這一個字段就存儲了應(yīng)用層生成的HTTP報文。ACK、SYN和FIN是在建立連接和關(guān)閉連接時使用。其他用于流量控制、擁塞管理等用途的字符就不展開了。5、路由尋址現(xiàn)在兩個端系統(tǒng)已經(jīng)建立起了連接,請求也被傳送到客戶端主機的網(wǎng)絡(luò)層。網(wǎng)絡(luò)層是協(xié)議棧中最復(fù)雜的層次,應(yīng)用層和傳輸層只運行在兩個端系統(tǒng),而網(wǎng)絡(luò)層不僅運行在端系統(tǒng),還運行在各個中間節(jié)點上。我們先來看看IP數(shù)據(jù)報的格式。網(wǎng)絡(luò)層實現(xiàn)的最重要的功能是路由選擇,簡單地說,就是怎么把這一個IP數(shù)據(jù)報從客戶端主機出發(fā),通過網(wǎng)絡(luò)中的若干個路由器,到達目的主機。從概念上講,IP路由選擇是簡單的,特別對于主機來說,如果目的主機和源主機直接相連(如點對點鏈路),或都在一個共享網(wǎng)絡(luò)上(以太網(wǎng)或令牌環(huán)網(wǎng)),那么IP數(shù)據(jù)報就直接送到目的主機上。否則,主機把數(shù)據(jù)報發(fā)送到一默認的路由器上,由路由器來轉(zhuǎn)發(fā)該數(shù)據(jù)報。大多數(shù)的主機都采用這種簡單機制。


網(wǎng)絡(luò)層實現(xiàn)的最重要的功能是路由選擇,簡單地說,就是怎么把這一個IP數(shù)據(jù)報從客戶端主機出發(fā),通過網(wǎng)絡(luò)中的若干個路由器,到達目的主機。從概念上講,IP路由選擇是簡單的,特別對于主機來說,如果目的主機和源主機直接相連(如點對點鏈路),或都在一個共享網(wǎng)絡(luò)上(以太網(wǎng)或令牌環(huán)網(wǎng)),那么IP數(shù)據(jù)報就直接送到目的主機上。否則,主機把數(shù)據(jù)報發(fā)送到一默認的路由器上,由路由器來轉(zhuǎn)發(fā)該數(shù)據(jù)報。大多數(shù)的主機都采用這種簡單機制。我們把網(wǎng)絡(luò)環(huán)境簡化如下圖:只包含源主機H1、目的主機H2和兩個路由器R1、R2。
IP路由選擇是逐跳(hop-to-hop)進行的。IP并不知道從H1到H2的完整路徑。所有的IP選擇只為數(shù)據(jù)報提供下一站的IP地址。路由選擇機制的基礎(chǔ)是在每一臺主機和路由器里都存儲著一張路由表。路由表的每一項包含了目的主機IP地址、下一跳路由器(或主機)的IP地址、相對應(yīng)的網(wǎng)絡(luò)接口以及其他必要的信息。當一個數(shù)據(jù)報到達一個節(jié)點時,IP路由選擇完成以下工作:搜索路由表,尋找能與目的主機IP地址完全匹配的表目。如果找到,則把報文發(fā)送給下一跳節(jié)點。
搜索路由表,尋找能與目標網(wǎng)絡(luò)號相匹配的表目。如果找到,則把報文發(fā)送給下一跳節(jié)點。
搜索路由表,尋找“默認”的表目。如果找到,則把報文發(fā)送給下一跳節(jié)點。

如果上面這些步驟都沒有成功,那么該數(shù)據(jù)報就不能被傳送。如果不能傳送的數(shù)據(jù)報來自本機,那么一般會向生成數(shù)據(jù)報的應(yīng)用程序返回一個“主機不可達”或“網(wǎng)絡(luò)不可達”的錯誤。在我們的例子中,H1通過搜索自己的路由表將數(shù)據(jù)報轉(zhuǎn)發(fā)給R1,R1根據(jù)路由表轉(zhuǎn)發(fā)給R2,最后到達H2。6、關(guān)閉連接目標主機收到了請求后,自底向上地對該請求進行處理。鏈路層把數(shù)據(jù)報傳給網(wǎng)絡(luò)層,網(wǎng)路層將TCP數(shù)據(jù)段通過對應(yīng)的Socket傳給應(yīng)用程序。應(yīng)用程序處理請求后產(chǎn)生一個應(yīng)答的HTTP報文,又經(jīng)過了一層層的封裝、一跳跳的傳輸?shù)竭_了源主機。這樣就結(jié)束了嗎?那一條TCP連接還沒有關(guān)閉呢,源主機和目標主機上都為它分配了資源呢,如果不釋放掉的話資源很快就會耗盡(DDoS攻擊就是利用這一點)。于是,當傳輸層收到了應(yīng)答之后,就要關(guān)閉這條連接了。但是,又不能悄悄地自己關(guān)了,目標主機那邊還不知道你要不要關(guān)閉呢。于是乎,就有了對應(yīng)創(chuàng)建TCP連接“三次握手”的關(guān)閉TCP連接“四次揮手”。如下圖所示,客戶端向服務(wù)器發(fā)出了FIN報文段,服務(wù)器收到后,回復(fù)一個ACK應(yīng)答。然后,服務(wù)器也向客戶端發(fā)送一個FIN報文段,隨后關(guān)閉了服務(wù)器端的連接,釋放了資源。當客戶端收到之后,又向服務(wù)器回復(fù)一個ACK應(yīng)答。過了一段計時等待,客戶端也關(guān)閉了連接,釋放資源。這一段計時等待的時間是為了客戶端重傳最后的ACK防止其丟失。


剩下的事情,就交給瀏覽器了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容