深入淺出經典面試題:從瀏覽器中輸入URL到頁面載入發生了什麼 - Part 2

張太國發表於2018-12-04

備註

因為文章太長,所以將它分為三部分,本文是第二部分。

第一部分深入淺出經典面試題:從瀏覽器中輸入URL到頁面載入發生了什麼 - Part 1

第二部分深入淺出經典面試題:從瀏覽器中輸入URL到頁面載入發生了什麼 - Part 2

第三部分深入淺出經典面試題:從瀏覽器中輸入URL到頁面載入發生了什麼 - Part 3

TCP連線

DNS解析返回域名的IP之後,接下來就是瀏覽器要和該IP建立TCP連線了。為什麼是TCP而不是UDP?那是因為HTTP是基於TCP上的。這裡涉及到另外一個話題:TCP/IP 模型。這個已經在大學的課本上學過了,我們再複習一下。
 

TCP/IP模型

TCP/IP模型一般分為4層,下面是我用PPT畫的。
在這裡不得不說OSI七層參考模型,它和TCP/IP模型的區別和聯絡,繼續用PPT畫,見下圖:

不多解釋,OSI的7/6/5層和TCP/TP的應用層對應,2/1層和鏈路層對應。在實際的應用中,主要還是TCP/IP概念模型,後面的內容主要講它。

這些都是課本上的,也許忘了(畢竟不是天天用到這些嘛),沒關係,我們以最簡單的方式來講解。為了便於理解每層的含義和作用,先看每層有哪些協議,看看有沒有自己熟悉的協議。有熟悉的協議,先體會一下。

應用層
我們可以看到,有常用的HTTP/HTTPS/IMAP/SSH/Telnet等都在應用層上(題外話,這一層你用的協議越多,說明你知識越開闊)。相信每個人都用過HTTP/HTTPS,所以我上面說HTTP/HTTP是基於TCP上的。
Wikipedia 這麼解釋:
The application layer is the scope within which applications create user data and communicate this data to other applications on another or the same host. The applications, or processes, make use of the services provided by the underlying, lower layers, especially the Transport Layer which provides reliable or unreliable pipesto other processes. The communications partners are characterized by the application architecture, such as the client-server model and peer-to-peer networking. This is the layer in which all higher level protocols, such as SMTP, FTP, SSH, HTTP, operate. Processes are addressed via ports which essentially represent services.
 
傳輸層
沒錯,最常見的TCP和UDP就在這裡,TCP三次握手也在這裡。
Wikipedia 這麼解釋:
The transport layer performs host-to-host communications on either the same or different hosts and on either the local network or remote networks separated by routers.[22] It provides a channel for the communication needs of applications. UDP is the basic transport layer protocol, providing an unreliable datagram service. The Transmission Control Protocol provides flow-control, connection establishment, and reliable transmission of data.
 
IP層
IP層非常重要,可能這麼說還不太懂,看看其他協議。大家知道ICMP嗎?估計很多人還是說不上來ICMP是什麼東西。大家肯定用過ping命令吧,它就是用的ICMP。說到這裡,應該有感性的認識了吧。
Wikipedia 這麼解釋:
The internet layer exchanges datagrams across network boundaries. It provides a uniform networking interface that hides the actual topology (layout) of the underlying network connections. It is therefore also referred to as the layer that establishes internetworking. Indeed, it defines and establishes the Internet. This layer defines the addressing and routing structures used for the TCP/IP protocol suite. The primary protocol in this scope is the Internet Protocol, which defines IP addresses. Its function in routing is to transport datagrams to the next IP router that has the connectivity to a network closer to the final data destination.
 
鏈路層
這個非常底層了,ARP,NDP,Ethernet都很常見,如果認真看過HTTP抓包,熟悉LVS,Ngnix等提供的負載均衡,應該對ARP不陌生,是的ARP用來查詢裝置的MAC地址,在LVS做負載均衡時會用到,因為進來的stream的包MAC地址要和出去的Stream包的MAC地址保持一致,因為做負載均衡,有可能會變化,如何解決這個問題,則不在本文的討論範圍內,如有興趣可以參看LVS的文件。
Wikipedia 這麼解釋:
The link layer defines the networking methods within the scope of the local network link on which hosts communicate without intervening routers. This layer includes the protocols used to describe the local network topology and the interfaces needed to effect transmission of Internet layer datagrams to next-neighbor hosts.

 

TCP/IP抓包分析

看了前面的內容,還是覺得抽象嗎?如果是,不要緊,也在預期內。讓我們抓個包,分析認識一下就清楚了。
 
先訪問www.qq.com 這個主頁,抓到的包如下:
 
看到這裡,應該開始有感覺了吧。
HTTP,即應用層,正在訪問js.aq.qq.com.
TCP層,src port是62957, dst port是80埠,因為js.aq.qq.com的埠是80。
IP層,用的是IPV4,我的計算機IP地址是192.168.1.2,目標IP是180.153.105.248.
鏈路層, 我使用的是Apple電腦,我的MAC地址我隱藏了,對端是ZTE裝置。
 
再截幾個圖大家仔細看一下。
鏈路層
 
IP層

TCP層
 
應用層(HTTP)

 

在這裡不加以詳解,後面會對TCP以及HTTP層詳詳細說明。

TCP三次握手與四次揮手

 
TCP三次握手
 
所謂三次握手(Three-way Handshake),是指建立一個 TCP 連線時,需要客戶端和伺服器總共傳送3個包。
三次握手的目的是連線伺服器指定埠,建立 TCP 連線,並同步連線雙方的序列號和確認號,交換 TCP 視窗大小資訊。在 socket 程式設計中,客戶端執行 connect() 時。將觸發三次握手。
·       第一次握手(SYN=1, seq=x):
客戶端傳送一個 TCP 的 SYN 標誌位置1的包,指明客戶端打算連線的伺服器的埠,以及初始序號 X,儲存在包頭的序列號(Sequence Number)欄位裡。
傳送完畢後,客戶端進入 SYN_SEND 狀態。
·       第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
伺服器發回確認包(ACK)應答。即 SYN 標誌位和 ACK 標誌位均為1。伺服器端選擇自己 ISN 序列號,放到 Seq 域裡,同時將確認序號(Acknowledgement Number)設定為客戶的 ISN 加1,即X+1。 傳送完畢後,伺服器端進入 SYN_RCVD 狀態。
·       第三次握手(ACK=1,ACKnum=y+1)
客戶端再次傳送確認包(ACK),SYN 標誌位為0,ACK 標誌位為1,並且把伺服器發來 ACK 的序號欄位+1,放在確定欄位中傳送給對方,並且在資料段放寫ISN的+1
傳送完畢後,客戶端進入 ESTABLISHED 狀態,當伺服器端接收到這個包時,也進入 ESTABLISHED狀態,TCP 握手結束。
三次握手的過程的示意圖如下:

 

確實比較抽象,讓我們繼續通過抓包來分析(訪問baidu.com)
這裡有三個包。
192.168.1.2是我機器的IP,115.239.211.112是baidu的IP,是不是和上圖一致。
具體看270包,192.168.1.2 傳送SYN到115.239.211.112,seq=0;
如下圖:

 

274包圖,115.239.211.112返回SYN 和ACK給192.168.1.2, seq =0, 但是ACK等於SYN裡的seq(為0)+1,所以為1

275包圖,192.168.1.2收到ACK包後,給115.239.211.112再回一個ACK,ACK#為1:

對於協議的理解,還是多觀察,多比對,就知道是怎麼回事了。

 

TCP四次揮手
TCP 連線的拆除需要傳送四個包,因此稱為四次揮手(Four-way handshake),也叫做改進的三次握手。客戶端或伺服器均可主動發起揮手動作,在 socket 程式設計中,任何一方執行 close() 操作即可產生揮手操作。
·       第一次揮手(FIN=1,seq=x)
假設客戶端想要關閉連線,客戶端傳送一個 FIN 標誌位置為1的包,表示自己已經沒有資料可以傳送了,但是仍然可以接受資料。
傳送完畢後,客戶端進入 FIN_WAIT_1 狀態。
·       第二次揮手(ACK=1,ACKnum=x+1)
伺服器端確認客戶端的 FIN 包,傳送一個確認包,表明自己接受到了客戶端關閉連線的請求,但還沒有準備好關閉連線。
傳送完畢後,伺服器端進入 CLOSE_WAIT 狀態,客戶端接收到這個確認包之後,進入 FIN_WAIT_2 狀態,等待伺服器端關閉連線。
·       第三次揮手(FIN=1,seq=y)
伺服器端準備好關閉連線時,向客戶端傳送結束連線請求,FIN 置為1。
傳送完畢後,伺服器端進入 LAST_ACK 狀態,等待來自客戶端的最後一個ACK。
·       第四次揮手(ACK=1,ACKnum=y+1)
客戶端接收到來自伺服器端的關閉請求,傳送一個確認包,並進入 TIME_WAIT狀態,等待可能出現的要求重傳的 ACK 包。
伺服器端接收到這個確認包之後,關閉連線,進入 CLOSED 狀態。
客戶端等待了某個固定時間(兩個最大段生命週期,2MSL,2 Maximum Segment Lifetime)之後,沒有收到伺服器端的 ACK ,認為伺服器端已經正常關閉連線,於是自己也關閉連線,進入 CLOSED 狀態。
 
四次揮手的示意圖如下:

這裡就不抓包了,可以自行抓包對比看看。

HTTPS證書

越來越多的網站開始使用HTTPS(Apple要求App都須用HTTPS)。對於HTTPS,需要有一個SSL/TLS的鑑權/認證,才能建立TCP連結。
 
下圖描述了HTTP和HTTPS的區別。

 

關於SSL/TLS如何互動等,可以參看阮一峰老師的文章http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html 和http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html,寫非常清楚的。
借用一張阮一峰老師的圖:

 

 

 

我們還是抓包體會一下。

 

對著阮一峰老師圖片的流程看:
273包: Client 傳送Client Hello給Server。
278包: Server回Server Hello給Client。
283包: Server繼續回Server Certificate給Client,要交換證書。
294包:Server繼續回Server Key Exchange,交換key。
295包:Server返回Server Hello Done。
截止這裡,Server已經做了不少事,接下來輪到Client了。
298包:Client Key Exchange,Change Cipher Spec,Encrypted Handshake Message。到這裡就結束了。
 
我們再仔細看看Client Hello的273包,注意標記部分.
接下來再看看Extension,有很多對不對。這裡專門說一下 SNI(Server Name Indication), server_name, 我們可以看見它的值是www.baidu.com. 也就是說瀏覽器傳送過來的證書是給baidu這個域名簽發的。SNI用來校驗該證書是不是為server name提供的域名簽發的。如果不是,就會報錯。
 
有一種情況特別需要注意,在早期版本的瀏覽器或者HTTP客戶端,SNI可能不包含在該包裡的,那麼怎麼處理呢?如果Server端只有一個證書部署,那簡單,就是按照部署的那個證書去判斷。如果有多個證書部署呢?比如部署了aaa.com bbb.com ccc.com 三個域名的證書,那麼就會按照預設的去匹配,取決於軟體(Apache,Tomcat等)和硬體(F5,Netscaler)怎麼配置了。
但是如果已經商用,去改預設配置,會對商用服務有影響,那麼可不可以在Client有一些改進呢?如果您正在使用某個HTTP library,可以考慮升級版本是否支援。
 

 

278包的Server Hello

繼續看看Server Certificate,即283包
我們看看baidu的證書,開啟Chrome就可以看到了,對比一下兩圖的基本資訊,這時是不是覺得更容易理解?我相信答案是肯定的。
294包,Server key Exchange

 

 
295包,Server Hello Done。

 

298包,Client Key Exchange/Change Cipher Spec/Encrypted Handshake Message。

TCP/IP其他

上面都是最基本的東西,在實際的過程中還有包重試,包拼裝等,太底層了,大家有興趣可以找資料看看。

TCP/IP 10問

以下幾個問題大部分都可以找到答案。
  1. TCP/IP的4層模型瞭解嗎?每層有哪些常見協議?
  2. TCP/IP的三次握手瞭解嗎?四次揮手是什麼,瞭解多少?
  3. HTTP和HTTPS在TCP握手上有什麼不同?SSL/TLS握手流程瞭解嗎?
  4. SSL/TLS的版本有哪些?當前瀏覽器支援哪些版本?
  5. SNI瞭解多少?如果SNI沒有,該如何校驗證書?
  6. TCP與UDP區別在哪裡?
  7. 為什麼TCP經常會組裝包?如何保證包的完整性?
  8. TCP滑動視窗原理是什麼?TCP有哪些狀態?
  9. MAC地址的是如何定義的?(這個問題太Edge了)
  10. SSL/TLS證書和埠有關係嗎?為什麼?

今天把TCP/IP, SSL/TLS介紹完了,下一部分是最後一部份了,左右介紹HTTP和Broswer的機制。

相關文章