【知識詳解】從輸入網址後發生了什麼

輸入網址後發生了什麼

1. DNS域名解析

從咱們是輸入的URL到得到目的ip地址的過程,這是一個遞歸查詢的過程。
首先應該查詢緩存,依次查找瀏覽器DNS緩存-->本地系統DNS緩存-->本地計算機host文件-->ISP的DNS緩存-->遞歸搜索。
遞歸搜索的順序:根域名服務器-->com頂級域名服務器-->google.com域名服務器
因此網址的真正解析過程:.-->.com-->google.com-->www.google.com.php

DNS域名搜索

2. 創建TCP鏈接(三次握手)

各參數意義:css

序列號seq:表示發送的數據序號x;
確認號ack:指望收到的下一個數據信號x+1;
同步標誌位SYN: SYN=1表示是一個鏈接請求或鏈接接受;
確認標誌位ACK: ACK=1表示確認號字段有效;
終止標誌位FIN: FIN=1表示發送完畢,要求釋放鏈接;

SYN鏈接創建報文
ACK應答報文
FIN鏈接釋放報文

客戶機發SYN消息-->服務器使用SYN+ACK表示收到了這個消息-->客戶機再以ACK響應

三次握手

  • 第一次握手:SYN=1,seq=x,進入SYN-SENT狀態,等待確認;
  • 第二次握手:SYN=1, ACK=1, seq=y, ack=x+1(確認對方的,發送本身),進入SYN-RECV狀態;
  • 第三次握手:ACK=1, seq=x+1, ack=y+1(確認對方,發送本身),客戶端服務器進入ESTABLISHED狀態;

問:爲何是三次握手?

本質上是爲了在不可靠的信道創建可靠的鏈接,防止已經失效的報文忽然又到了服務器,假設客戶端發送了一個請求鏈接,可是由於信道的緣由發生了滯留,等了一會沒有收到確認,再次發送請求鏈接,此次信道狀況較好,很快進行了確認接受了鏈接,可是過了一會那個滯留的鏈接到達服務器,其實已是一個失效的報文了,服務器覺得客戶端再次發起新的鏈接,回覆確認。若是採用兩次握手,服務器發出確認後就創建了鏈接,可是客戶端並無發出鏈接的請求,因此不會理睬服務器的確認,那這樣服務器認爲鏈接已經創建,一直等待客戶端發送數據,形成資源的浪費。若是是三次握手的話,服務器會等着客戶端的確認,若是收不到確認,就知道客戶端並無想創建鏈接。html

3. 發送http請求

https過程:HTTPS在傳輸數據以前須要客戶端與服務器進行一個握手(TLS/SSL握手),在握手過程當中將確立雙方加密傳輸數據的密碼信息。TLS/SSL使用了非對稱加密,對稱加密以及hash等。具體可參考:Https詳解
HTTPS相比於HTTP,雖然提供了安全保證,可是勢必會帶來一些時間上的損耗,如握手和加密等過程,是否使用HTTPS須要根據具體狀況在安全和性能方面作出權衡。編程

Http過程
發送http請求就是構建http報文並經過TCP協議發送到服務器指定端口(http:80,https:443),報文由3部分組成:請求行,請求頭,請求體segmentfault

image

請求行
    Method Request-URL HTTP-Version CRLF
eg: GET index.html HTTP/1.1

方法有get、post、put、delete
URL:統一資源定位符;
組成:組成:<協議>://<主機>:<端口>/<路徑> 注:端口和路徑有時能夠省略(HTTP默認端口號是80)
好比:https://localhost:8080/index.html?key1=value1&keys2=value2後端

問:get和post有什麼區別?

一、在沒有參數時二者的請求行中只有method不一樣;在帶參數時,get請求的數據會附在URL以後(放在請求行),以?分割,多個參數用&鏈接,而post請求會放在請求體中,好比,若是參數是:name=xin, age=22
get方法的報文:瀏覽器

GET /index.php?name=xin&age=22 HTTP/1.1
Host: localhost

post方法的報文緩存

POST /index.php HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

name=xin&age=22

二、從URL來看post請求比get請求要安全,由於參數信息不會顯示在地址欄上,但從傳輸上來看二者都是不安全的,由於都是用的http,在網絡上上是明文傳輸,隨時均可能被抓包獲取。
三、get方法在瀏覽器地址欄上輸入的參數是有限的,這並非http協議的限制,而是瀏覽器和服務器的限制。而post請求請求體並無長度限制。因此get請求傳輸數據較少,post請求能傳輸大量數據。
四、get主要用於信息獲取。不會增長或修改資源,只是查詢。post主要用於更新資源信息。
五、get方法產生一個TCP數據包,瀏覽器會把請求頭和請求體一併發出去,服務器響應200 ok。post方法產生兩個TCP數據包,瀏覽器會先把請求頭髮給服務器,返回100 continue,再發請求體,返回200 ok。
它們的本質都是 TCP 連接,並沒有區別。可是因爲 HTTP 的規定以及瀏覽器/服務器的限制,致使它們在應用過程當中可能會有所不一樣。安全

4. 服務器處理請求並返回HTTP報文

後端從固定的端口收到TCP報文後,這一部分對應編程語言的socket,它會對TCP鏈接進行處理,對HTTP協議進行解析,並按照報文格式進一步封裝成HTTP Request對象,供上層使用,這一部分工做由Web服務器進行,好比Tomcat。
HTTP響應報文也由3部分組成:狀態碼,響應頭,響應體;服務器

狀態碼
狀態碼就是服務器告訴客戶端,發送了什麼事;

問:常見狀態碼?

1**:指示信息--表示請求已接收,繼續處理;
2**:成功--表示請求已被成功接收、理解、接受
   200 OK 服務器成功處理了請求
3**:重定向--要完成請求必須更進一步的操做
   301/302 Moved Permanently 請求的URL已移走,Response中應該包含一個Location URL, 說明資源如今所處的位置
4**:客戶端錯誤--請求有語法錯誤或請求沒法實現
   404 Not Found 未找到資源
5**:服務端錯誤--服務器未能實現合法的請求(本身出錯了或網站都掛了)
   501 Internal Server Error服務器遇到一個錯誤,使其沒法爲請求提供服務

響應頭
響應體
服務器返回給瀏覽器的信息,好比html、css、js等。

5. 瀏覽器解析渲染頁面

瀏覽器解析HTML文件構建DOM樹,每一個標籤都是一個節點;
解析CSS文件構建渲染樹。這是一個很複雜的過程。

6. 釋放TCP鏈接(四次揮手)

四次揮手

  • 1.客戶端發出鏈接釋放報文,中止發送數據,FIN=1,seq=u(等於前面傳過來的最後一個序列號+1,TCP規定FIN報文段即便不攜帶數據,也消耗一個序號),此時客戶端進入FIN-WAIT-1(終止等待1)狀態。
  • 2.服務器收到鏈接釋放報文,發出報文確認,ACK=1,ack=u+1,而且帶上本身的序列號,seq=v,此時服務器進入CLOSE-WAIT狀態,這時候客戶端不發了,可是服務端還要發,客戶端依然要接收。客戶端收到確認請求後,進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送鏈接釋放報文。
  • 3.服務器發送完畢後,向客戶端發送鏈接釋放報文,FIN=1,ACK=1,ack=u+1,seq=w,此時,服務器進入LAST-WAIT(最後確認)狀態,等待客戶端確認。
  • 4.客戶端收到鏈接釋放報文,發出報文確認,ACK=1,ack=w+1,本身的序列號還是seq=u+1,此時,客戶端進入TIME-WAIT(時間等待)狀態,注意此時TCP鏈接沒有釋放,必須等待2MSL(最長報文段壽命)時間後,纔會進入CLOSE(關閉)狀態。服務器只要收到了確認後,立馬進入CLOSED狀態。因此服務器結束時間要比客戶端早一些。

問:爲何握手是三次而揮手是四次?

由於服務器收到客戶端的SYN鏈接創建報文後,能夠直接發送SYN+ACK報文,即應答和同步,可是在關閉鏈接時,服務器可能還有數據要發送,因此只回復一個應答告訴客戶端本身收到了,可是我這不能關,得等我發完了,我才能發送FIN鏈接釋放報文。

問:爲何TIME-WAIT須要2MSL才能返回CLOSE狀態?**

由於信道是不可靠的,最後一個ACK確認報文發送後可能會丟失,服務器若是沒有收到ACK確認,就會重發FIN鏈接釋放報文,若是客戶端又收到了,那就知道剛纔那個確認丟失了,重發ACK確認。因此,當客戶端在2MSL時間內沒有再次收到FIN報文後,客戶端就知道服務器已經成功收到了,進入CLOSED狀態。

參考連接

三次握手和四次揮手
從輸入URL後發生了什麼
一個完整的http請求

相關文章
相關標籤/搜索