當我們在瀏覽器的地址欄輸入 www.linux178.com ,然後斷行符號,斷行符號這一瞬間到看到頁面到底發生了什麼呢。
以下過程僅是個人理解:
網域名稱解析 --> 發起TCP的3次握手 --> 建立TCP串連後發起http請求 --> 伺服器響應http請求,瀏覽器得到html代碼 --> 瀏覽器解析html代碼,並請求html代碼中的資源(如js、css、圖片等) --> 瀏覽器對頁面進行渲染呈現給使用者
關於HTTP協議可以參考以下:
HTTP協議漫談 http://kb.cnblogs.com/page/140611/
HTTP協議概覽 http://www.cnblogs.com/vamei/archive/2013/05/11/3069788.html
瞭解HTTP Headers的方方面面 http://kb.cnblogs.com/page/55442/
以下就是上面過程的一一分析,我們就以Chrome瀏覽器為例:
1.網域名稱解析
首先Chrome瀏覽器會解析 www.linux178.com 這個網域名稱(準確的叫法應該是主機名稱)對應的IP地址。怎麼解析到對應的IP地址。
① Chrome瀏覽器 會首先搜尋瀏覽器自身的DNS緩衝(緩衝時間比較短,大概只有1分鐘,且只能容納1000條緩衝),看自身的緩衝中是否有www.linux178.com 對應的條目,而且沒有到期,如果有且沒有到期則解析到此結束。
註:我們怎麼查看Chrome自身的緩衝。可以使用 chrome://net-internals/#dns 來進行查看
② 如果瀏覽器自身的緩衝裡面沒有找到對應的條目,那麼Chrome會搜尋作業系統自身的DNS緩衝,如果找到且沒有到期則停止搜尋解析到此結束.
註:怎麼查看作業系統自身的DNS緩衝,以Windows系統為例,可以在命令列下使用 ipconfig /displaydns 來進行查看
③ 如果在Windows系統的DNS緩衝也沒有找到,那麼嘗試讀取hosts檔案(位於C:\Windows\System32\drivers\etc),看看這裡面有沒有該網域名稱對應的IP地址,如果有則解析成功。
④ 如果在hosts檔案中也沒有找到對應的條目,瀏覽器就會發起一個DNS的系統調用,就會向本地配置的首選DNS伺服器(一般是電信電訊廠商提供的,也可以使用像Google提供的DNS伺服器)發起網域名稱解析請求(通過的是UDP協議向DNS的53連接埠發起請求,這個請求是遞迴的請求,也就是電訊廠商的DNS伺服器必須得提供給我們該網域名稱的IP地址),電訊廠商的DNS伺服器首先尋找自身的緩衝,找到對應的條目,且沒有到期,則解析成功。如果沒有找到對應的條目,則有電訊廠商的DNS代我們的瀏覽器發起迭代DNS解析請求,它首先是會找根域的DNS的IP地址(這個DNS伺服器都內建13台根域的DNS的IP地址),找打根域的DNS地址,就會向其發起請求(請問www.linux178.com這個網域名稱的IP地址是多少啊。),根域發現這是一個頂級域com域的一個網域名稱,於是就告訴電訊廠商的DNS我不知道這個網域名稱的IP地址,但是我知道com域的IP地址,你去找它去,於是電訊廠商的DNS就得到了com域的IP地址,又向com域的IP地址發起了請求(請問www.linux178.com這個網域名稱的IP地址是多少?),com域這台伺服器告訴電訊廠商的DNS我不知道www.linux178.com這個網域名稱的IP地址,但是我知道linux178.com這個域的DNS地址,你去找它去,於是電訊廠商的DNS又向linux178.com這個網域名稱的DNS地址(這個一般就是由網域名稱註冊商提供的,像萬網,新網等)發起請求(請問www.linux178.com這個網域名稱的IP地址是多少。),這個時候linux178.com域的DNS伺服器一查,誒,果真在我這裡,於是就把找到的結果發送給電訊廠商的DNS伺服器,這個時候電訊廠商的DNS伺服器就拿到了www.linux178.com這個網域名稱對應的IP地址,並返回給Windows系統核心,核心又把結果返回給瀏覽器,終於瀏覽器拿到了www.linux178.com 對應的IP地址,該進行一步的動作了。
註:一般情況下是不會進行以下步驟的
如果經過以上的4個步驟,還沒有解析成功,那麼會進行如下步驟(以下是針對Windows作業系統):
⑤ 作業系統就會尋找NetBIOS name Cache(NetBIOS名稱緩衝,就存在用戶端電腦中的),那這個緩衝有什麼東西呢。凡是最近一段時間內和我成功通訊的電腦的電腦名稱和Ip地址,就都會存在這個緩衝裡面。什麼情況下該步能解析成功呢。就是該名稱正好是幾分鐘前和我成功通訊過,那麼這一步就可以成功解析。
⑥ 如果第⑤步也沒有成功,那會查詢WINS 伺服器(是NETBIOS名稱和IP地址對應的伺服器)
⑦ 如果第⑥步也沒有查詢成功,那麼用戶端就要進行廣播尋找
⑧ 如果第⑦步也沒有成功,那麼用戶端就讀取LMHOSTS檔案(和HOSTS檔案同一個目錄下,寫法也一樣)
如果第八步還沒有解析成功,那麼就宣告這次解析失敗,那就無法跟目標電腦進行通訊。只要這八步中有一步可以解析成功,那就可以成功和目標電腦進行通訊。
看下圖抓包截圖:
Linux虛擬機器測試,使用命令 wget www.linux178.com 來請求,發現直接使用chrome瀏覽器請求時,幹擾請求比較多,所以就使用wget命令來請求,不過使用wget命令只能把index.html請求回來,並不會對index.html中包含的靜態資源(js、css等檔案)進行請求。
抓包分析:
① 號包,這個是那台虛擬機器在廣播,要擷取192.168.100.254(也就是網關)的MAC地址,因為區域網路的通訊靠的是MAC地址,它為什麼需要跟網關進行通訊是因為我們的DNS伺服器IP是外圍IP,要出去必須要依靠網關幫我們出去才行。
② 號包,這個是網關收到了虛擬機器的廣播之後,回應給虛擬機器的回應,告訴虛擬機器自己的MAC地址,於是用戶端找到了路由出口。
③ 號包,這個包是wget命令向系統配置的DNS伺服器提出網域名稱解析請求(準確的說應該是wget發起了一個DNS解析的系統調用),請求的網域名稱www.linux178.com,期望得到的是IP6的地址(AAAA代表的是IPv6地址)
④ 號包,這個DNS伺服器給系統的響應,很顯然目前使用IPv6的還是極少數,所以得不到AAAA記錄的
⑤ 號包,這個還是請求解析IPv6地址,但是www.linux178.com.leo.com這個主機名稱是不存在的,所以得到結果就是no such name
⑥ 號包,這個才是請求的網域名稱對應的IPv4地址(A記錄)
⑦ 號包,DNS伺服器不管是從緩衝裡面,還是進行迭代查詢最終得到了網域名稱的IP地址,響應給了系統,系統再給了wget命令,wget於是得到了www.linux178.com的IP地址,這裡也可以看出用戶端和本地的DNS伺服器是遞迴的查詢(也就是伺服器必須給用戶端一個結果)這就可以開始下一步了,進行TCP的三向交握。
2.發起TCP的3次握手
拿到網域名稱對應的IP地址之後,User-Agent(一般是指瀏覽器)會以一個隨機連接埠(1024 < 連接埠 < 65535)向伺服器的WEB程式(常用的有httpd,nginx等)80連接埠發起TCP的串連請求。這個串連請求(原始的http請求經過TCP/IP4層模型的層層封包)到達伺服器端後(這中間通過各種路由裝置,區域網路內除外),進入到網卡,然後是進入到核心的TCP/IP協議棧(用於識別該串連請求,解鎖包,一層一層的剝開),還有可能要經過Netfilter防火牆(屬於核心的模組)的過濾,最終到達WEB程式(本文就以Nginx為例),最終建立了TCP/IP的串連。
如下圖:
1) Client首先發送一個串連試探,ACK=0 表示確認號無效,SYN = 1 表示這是一個串連請求或串連接受報文,同時表示這個資料報不能攜帶資料,seq = x 表示Client自己的初始序號(seq = 0 就代表這是第0號包),這時候Client進入syn_sent狀態,表示用戶端等待伺服器的回複
2) Server監聽到串連請求報文後,如同意建立串連,則向Client發送確認。TCP報文首部中的SYN 和 ACK都置1 ,ack = x + 1表示期望收到對方下一個報文段的第一個資料位元組序號是x+1,同時表明x為止的所有資料都已正確收到(ack=1其實是ack=0+1,也就是期望用戶端的第1個包),seq = y 表示Server 自己的初始序號(seq=0就代表這是伺服器這邊發出的第0號包)。這時伺服器進入syn_rcvd,表示伺服器已經收到Client的串連請求,等待client的確認。
3) Client收到確認後還需再次發送確認,同時攜帶要發送給Server的資料。ACK 置1 表示確認號ack= y + 1 有效(代表期望收到伺服器的第1個包),Client自己的序號seq= x + 1(表示這就是我的第1個包,相對於第0個包來說的),一旦收到Client的確認之後,這個TCP串連就進入Established狀態,就可以發起http請求了。
看抓包截圖:
⑨ 號包 這個就是對應上面的步驟 1)
⑩ 號包 這個對應的上面的步驟 2)
號包 這個對應的上面的步驟 3)
TCP 為什麼需要3次握手。
舉個例子:
假設一個老外在故宮裡面迷路了,看到了小明,於是就有下面的對話:
老外: Excuse me,Can you Speak English?
小明: yes 。
老外: OK,I want ...
在問路之前,老外先問小明是否會說英語,小明回答是的,這時老外才開始問路
2個電腦通訊是靠協議(目前流行的TCP/IP協議)來實現,如果2個電腦使用的協議不一樣,那是不能進行通訊的,所以這個3次握手就相當於試探一下對方是否遵循TCP/IP協議,協商完成後就可以進行通訊了,當然這樣理解不是那麼準確。
為什麼HTTP協議要基於TCP來實現。
目前在Internet中所有的傳輸都是通過TCP/IP進行的,HTTP協議作為TCP/IP模型中應用程式層的協議也不例外,TCP是一個端到端的可靠的連線導向的協議,所以HTTP基於傳輸層TCP協議不用擔心資料的傳輸的各種問題。
3.建立TCP串連後發起http請求
進過TCP3次握手之後,瀏覽器發起了http的請求(看第包),使用的http的方法 GET 方法,請求的URL是 / ,協議是HTTP/1.0
下面是第12號包的詳細內容:
以上的報文是HTTP請求報文。
那麼HTTP請求報文和響應報文會是什麼格式呢。
起始行:如 GET / HTTP/1.0 (請求的方法 請求的URL 請求所使用的協議)
頭部資訊:User-Agent Host等成對出現的值