瀏覽器請求的旅程

風中有朵雲做的雨發表於2019-04-28

流程圖

瀏覽器請求的旅程

DNS解析

  1. 本地域名伺服器查詢有沒有www.kaola.com所對應的ip
  2. 本地伺服器未查詢到,則去根域名伺服器查詢
  3. 根域名伺服器未找到相應ip,會返回一級域名伺服器地址
  4. 查詢一級域名伺服器
  5. 一級域名伺服器未找到相應ip,返回二級域名伺服器地址
  6. 查詢二級域名伺服器
  7. 二級域名伺服器檢視本地name.conf,是否有www主機的記錄
  8. 查到www主機的記錄,返回www主機的ip到二級域名伺服器
  9. 返回ip到本地域名伺服器
  10. 返回ip到瀏覽器

http請求

HTTP請求 客戶端根據域名得到相應ip以後開始傳送http請求,HTTP請求分為三個部分:
TCP三次握手、http請求響應資訊、關閉TCP連線

TCP三次握手

瀏覽器請求的旅程

http請求資訊

http請求報文 TTP請求報文由請求行(request line)、請求頭部(header)、請求主體三個部分組成。如下圖所示:

瀏覽器請求的旅程

  1. 請求行包含:請求方法、URL、協議版本 請求方法包含8種:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。 URL即請求地址,由 <協議>://<主機>:<埠>/<路徑>?<引數> 組成 協議版本即http版本號
  2. 請求頭部包含請求的附加資訊,由 名/值 對組成
    請求頭部通知伺服器有關於客戶端請求的資訊。它包含許多有關的客戶端環境和請求正文的有用資訊。其中比如:Host,表示主機名,虛擬主機;Connection,HTTP/1.1 增加的,使用 keepalive,即持久連線,一個連線可以發多個請求;User-Agent,請求發出者,相容性以及定製化需求
  3. 請求主體包含回車符、換行符和請求資料,並不是所有請求都具有請求資料

MVC

http請求報文傳送後,經過nginx伺服器轉發、服務端servlet處理請求之後,響應資訊會以響應報文的形式返回給客戶端。
後續開一章 比較偏後端的mvc整個請求

http響應資訊

響應報文由響應行(request line)、響應頭部(header)、響應主體三個部分組成。如下圖所示:

瀏覽器請求的旅程

  1. 響應行包含:協議版本,狀態碼,狀態碼描述
    狀態碼規則如下:
    1xx:指示資訊--表示請求已接收,繼續處理。
    2xx:成功--表示請求已被成功接收、理解、接受。
    3xx:重定向--要完成請求必須進行更進一步的操作。
    4xx:客戶端錯誤--請求有語法錯誤或請求無法實現。
    5xx:伺服器端錯誤--伺服器未能實現合法的請求。
  2. 響應頭部包含響應報文的附加資訊,由 名/值 對組成
  3. 響應主體包含回車符、換行符和響應返回資料,並不是所有響應報文都有響應資料

關閉TCP連線

瀏覽器請求的旅程

瀏覽器處理返回的資訊(html、json等)

瀏覽器處理

TCP擴充

拿到域名對應的IP地址之後,User-Agent(一般是指瀏覽器)會以一個隨機埠(1024 < 埠 < 65535)向伺服器的WEB程式(常用的有httpd,nginx等)80埠發起TCP的連線請求。這個連線請求(原始的http請求經過TCP/IP4層模型的層層封包)到達伺服器端後(這中間通過各種路由裝置,區域網內除外),進入到網路卡,然後是進入到核心的TCP/IP協議棧(用於識別該連線請求,解封包,一層一層的剝開),還有可能要經過Netfilter防火牆(屬於核心的模組)的過濾,最終到達WEB程式

TCP報文格式

TCP/IP協議的詳細資訊參看《TCP/IP協議詳解》三卷本。
下面是TCP報文格式圖:

瀏覽器請求的旅程
上圖中有幾個欄位需要重點介紹下:
(1)序號:Seq序號,佔32位,用來標識從TCP源端向目的端傳送的位元組流,發起方傳送資料時對此進行標記。
(2)確認序號:ack序號,佔32位,只有ACK標誌位為1時,確認序號欄位才有效,Ack=Seq+1。
(3)標誌位:共6個,即URG、ACK、PSH、RST、SYN、FIN等,具體含義如下:

  • URG:緊急指標(urgent pointer)有效。
  • ACK:確認序號有效。
  • PSH:接收方應該儘快將這個報文交給應用層。
  • RST:重置連線。
  • SYN:發起一個新連線。
  • FIN:釋放一個連線。

seq:首次是隨機產生 後面是等於返回的ack
ack:期望收到對方下一個報文段的第一個資料位元組序號

TCP三次握手

瀏覽器請求的旅程
假如伺服器B和客戶機A通訊. 當A要和B通訊時

  1. A首先向B發一個SYN (Synchronize) 標記的包,告訴B請求建立連線. 注意: 一個 SYN包就是僅SYN標記設為1的TCP包. 只有當B受到A發來的SYN包,才可建立連線,除此之外別無他法。
  2. 接著,B收到後會發一個對SYN包的確認包(SYN/ACK)回去,表示對第一個SYN包的確認,並繼續握手操作. 注意: SYN/ACK包是僅SYN 和 ACK 標記為1的包.
  3. A收到SYN/ACK 包,A發一個確認包(ACK),通知B連線已建立。至此,三次握手完成,一個TCP連線完成 注意: ACK包就是僅ACK 標記設為1的TCP包.
序號 方向 seq ack SYN ACK
1 A->B 10000 0 1 0
2 B->A 20000 10000+1=10001 1 1
3 A->B 10001 20000+1=20001 0 1

第一次握手:A向B發起連線請求,以一個隨機數初始化A的seq,這裡假設為10000,此時ACK=0
第二次握手:B收到A的連線請求後,也以一個隨機數初始化B的seq,這裡假設為20000,意思是:你的請求我已收到,我這方的資料流就從這個數開始。B的ack是A的seq加1,即10000+1=10001
第三次握手:A收到B的回覆後,它的seq是它的上個請求的seq加1,即10000+1=10001,意思也是:你的回覆我收到了,我這方的資料流就從這個數開始。A此時的ACK是B的seq加1,即20000+1=20001

資料傳輸過程中seq和ack的值:

序號 方向 seq ack size
23 A->B 40000 70000 1514
24 B->A 70000 40000+1514-54=41460 54
25 A->B 41460 70000+54-54=70000 1514
26 B->A 70000 41460+1514-54=42920 54

這個54可以先不考慮 當做不存在即可 有興趣自己查查

TCP四次揮手

瀏覽器請求的旅程
假如伺服器B和客戶機A通訊. 當A要和B通訊時

  1. 客戶端A沒有要傳送給服務端B的資料了,想要關閉連結,則傳送一個FIN=1,ACK=1的包,告訴B可以關閉連線了,我沒有什麼資料要給你了。
  2. 然後B會傳送ACK=1的包給A,告訴A我知道你沒有什麼想給我的了,但是我還有資料要給你,你先等下,我先不想FINISH呢。
  3. 等B把資料都傳送給A之後,B會再次傳送一個包,這次FIN=1,表示我這邊也想關閉了,我們倆一起關把 。
    在2和3之間,可能還會有很多B->A的傳遞,ack均為80001
  4. 然後A回應一個ACK,表示我知道了,一起關吧。B收到這個ACK後,就會CLOSE 但是實際上A不會直接CLOSE,還會進入一個等待時間狀態TIME_WAIT

四次揮手過程中seq和ack的值:

TCP連線的結束是四次揮手的過程,ACK一直等於1

序號 方向 seq ack FIN ACK
1 A->B 80000 90000 1 1
2 B->A 90000 80000+1=80001 0 1
3 B->A 95000 80001 1 1
4 A->B 80001 95000+1=95001 0 1

參考

github.com/kaola-fed/b…

相關文章