詳解輸入網址點擊回車,後臺到底發生了什麼。透析 HTTP 協議與 TCP 鏈接之間的千絲萬縷的關係。掌握爲什麼是三次握手四次揮手? time_wait 存在的意義是什麼?全面圖解重點問題,不再用擔憂面試問這個問題。java
大體流程面試
重點來了:數據庫
繼續閱讀本文,且聽碼哥字節答疑解惑,微信搜索 「碼哥字節」,關注公衆號更多硬核。segmentfault
好比 【碼哥字節】在思否發佈的一篇文章的地址:https://segmentfault.com/a/1190000023475177。url 遵照的規則是這個樣子瀏覽器
scheme://host.domain:port/path/filename
每一個名詞的含義以下解釋:緩存
瀏覽器不能直接經過域名找到服務器,只能經過 IP 地址。服務器
那瀏覽器是如何經過域名查詢到咱們輸入的 url 對應的 IP 呢?微信
經過域名解析出 IP 地址之後就要創建 TCP/IP 鏈接了。網絡
TCP/IP 分爲四層,每一層都會加上一個頭部再發送給下一層。到了接收方後,對應的每一層則把對應層的頭部解析拆除,丟上上一層,跟發送端的過程反過來。架構
瀏覽器從地址欄獲得服務器 IP,接着構造一個 HTTP 報文,其中包括:
請求行包含請求方法、URL、協議版本
name=tom&password=1234&realName=tomson
,也能夠將參數放在 body 裏面。在傳輸報文以前會先創建 TCP/IP 鏈接,也就是後面咱們要說的三次握手。
在這一層解決了數據可靠傳輸、及流量控制、擁塞控制。
可靠傳輸
對於發送方發送的數據,接收方在接受到數據以後必需要給予確認,確認它收到了數據。若是在規定時間內,沒有給予確認則意味着接收方沒有接受到數據,而後發送方對數據進行重發。
TCP的可靠傳輸是經過確認和超時重傳的機制來實現的,而確認和超時重傳的具體的實現是經過以字節爲單位的滑動窗口機制來完成。
TCP擁塞控制
TCP協議經過慢啓動機制、擁塞避免機制、加速遞減機制、快重傳和快恢復機制來共同實現擁塞控制。
流量控制
採用通知窗口實現對發送端的流量控制,通知窗口大小的單位是字節。TCP經過在TCP數據段首部的窗口字段中填入當前設定的接收窗口(即通知窗口)的大小,用來告知對方 '我方當前的接收窗口大小',以實現流量控制。
通訊雙方的發送窗口大小由雙方在鏈接創建的時候商定,在通訊過程,雙方能夠動態地根據本身的狀況調整對方的發送窗口大小。
將數據段打包,並加入源及目標的 IP 地址,而且負責尋找傳輸路線。判斷目標地址是否與當前地址處於同一網絡中,是的話直接根據 Mac 地址發送,不然使用路由表查找下一跳地址,以及使用 ARP 協議查詢它的 Mac 地址。
根據以太網協議將數據分爲以「幀」爲單位的數據包,每一幀分爲兩個部分:
以太網規定了連入網絡的全部設備都必須具有「網卡」接口,數據包都是從一塊網卡傳遞到另外一塊網卡,網卡的地址就是 Mac 地址。每個 Mac 地址都是獨一無二的,具有了一對一的能力。
在傳輸層傳輸數據以前須要創建鏈接,也就是三次握手建立可靠鏈接。
首先創建連接前須要 Server 端先監聽端口,所以 Server 端創建連接前的初始狀態就是 LISTEN 狀態,這時 Client 端準備創建連接,先發送一個 SYN 同步包,發送完同步包後,Client 端的連接狀態變成了 SYN_SENT 狀態。Server 端收到 SYN 後,贊成創建連接,會向 Client 端回覆一個 ACK。
因爲 TCP 是雙工傳輸,Server 端也會同時向 Client 端發送一個 SYN,申請 Server 向 Client 方向創建連接。發送完 ACK 和 SYN 後,Server 端的連接狀態就變成了 SYN_RCVD。
Client 收到 Server 的 ACK 後,Client 端的連接狀態就變成了 ESTABLISHED 狀態,同時,Client 向 Server 端發送 ACK,回覆 Server 端的 SYN 請求。
Server 端收到 Client 端的 ACK 後,Server 端的連接狀態也就變成了的 ESTABLISHED 狀態,此時建連完成,雙方隨時能夠進行數據傳輸。
在面試時須要明白三次握手是爲了創建雙向的連接,須要記住 Client 端和 Server 端的連接狀態變化。另外回答建連的問題時,能夠提到 SYN 洪水***發生的緣由,就是 Server 端收到 Client 端的 SYN 請求後,發送了 ACK 和 SYN,可是 Client 端不進行回覆,致使 Server 端大量的連接處在 SYN_RCVD 狀態,進而影響其餘正常請求的建連。能夠設置 tcp_synack_retries = 0 加快半連接的回收速度,或者調大 tcp_max_syn_backlog 來應對少許的 SYN 洪水***
咱們只要關注 80 端口與 13743 端口創建的鏈接斷開過程,瀏覽器經過 13747 端口發送 [FIN, ACK] 這裏是否是跟不少網上看到的不同?
實際上是客戶端在發送 [FIN] 報文的時候順帶發了一個 [ACK] 確認上次傳輸確認。
具體流程以下圖抓包所示:
三次握手與四次揮手
客戶端:
服務端:
TIME_WAIT 狀態存在的理由:
劃重點了
另外回答斷鏈的問題時,能夠提到實際應用中有可能遇到大量 Socket 處在 TIME_WAIT 或者 CLOSE_WAIT 狀態的問題。通常開啓 tcp_tw_reuse 和 tcp_tw_recycle 可以加快 TIME-WAIT 的 Sockets 回收;而大量 CLOSE_WAIT 多是被動關閉的一方存在代碼 bug,沒有正確關閉連接致使的。
簡單地說就是
深刻分析下 HTTP 報文究竟是什麼玩意。數據傳輸都是經過 TCP/IP 協議負責底層的傳輸工做, HTTP 協議基本不用操心,所謂的 「超文本傳輸協議」 彷佛不怎麼例會 「傳輸」 這個事情,那 HTTP 的核心又是什麼呢?
比圖 TCP 報文,它在實際要傳輸的數據以前附加了一個 20 字節的頭部數據,存儲 TCP 協議必須的額外信息,例如發送方的端口號、接收方的端口號、包序號、標誌位等等。
有了這個附加的 TCP 頭,數據包纔可以正確傳輸,到了目的地後把頭部去掉,就能夠拿到真正的數據。這個很容易理解,設置起點與終點,不一樣協議貼上不一樣的頭部,到了對應目的地就拆下這個頭部,提取真正的數據。
與 TCP/UDP 相似須要在傳輸數據前設置一些請求頭,不一樣的是 HTTP 是一個 「純文本」 的協議,全部的頭都是 ASCII 碼的文本,很容易看出來是什麼。
再者就是他的請求報文與響應報文的結構基本同樣,主要三大部分組成:
這其中前兩部分起始行和頭部字段常常又合稱爲「請求頭」或「響應頭」,消息正文又稱爲「實體」,但與「header」對應,不少時候就直接稱爲「body」。
敲黑板了
HTTP 協議規定報文必須包含 Header,並且以後必須有一個 「空行」,也就是「CRLF」,十六進制的「0D0A」,能夠沒有 「body」。
報文結構以下圖所示:
截取一段報文:
請求頭-起始行
請求行由請求方法字段、URL 字段和 HTTP 協議版本字段 3 個字段組成,它們用空格分隔。例如,GET / HTTP/1.1。
HTTP 協議的請求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT
。
GET 是請求方法, 「/」 是請求的目標資源,「HTTP/1.1」 請求協議版本號。
GET / HTTP/1.1
翻譯成文字大概就是:「hello,服務器,我要請求根目錄下的默認文件使用的是 HTTP 1.1 協議版本」。
頭部 Header
第二部分就是 Header,組成形式是 key:value,使用自定義頭須要注意事項:
接收到響應文本 HTML,則開始執行瀏覽器渲染機制。
不一樣的瀏覽器渲染可能有所差別,可是基本按照如下步驟執行:
推薦閱讀
如下幾篇文章閱讀量與讀者反饋都很好,推薦你們閱讀:
若是以爲閱讀後對你有幫助,但願多多分享、點贊與在看素質三連不作白嫖者。關注 【碼哥字節】解鎖更多硬核。
個人我的微信:MageByte1024