備注:
因為文章太長,所以將它分為三部分,本文是第二部分。
第一部分:深入淺出經典面試題:從瀏覽器中輸入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問
以下幾個問題大部分都可以找到答案。
- TCP/IP的4層模型了解嗎?每層有哪些常見協議?
- TCP/IP的三次握手了解嗎?四次揮手是什么,了解多少?
- HTTP和HTTPS在TCP握手上有什么不同?SSL/TLS握手流程了解嗎?
- SSL/TLS的版本有哪些?當前瀏覽器支持哪些版本?
- SNI了解多少?如果SNI沒有,該如何校驗證書?
- TCP與UDP區別在哪里?
- 為什么TCP經常會組裝包?如何保證包的完整性?
- TCP滑動窗口原理是什么?TCP有哪些狀態?
- MAC地址的是如何定義的?(這個問題太Edge了)
- SSL/TLS證書和端口有關系嗎?為什么?
今天把TCP/IP, SSL/TLS介紹完了,下一部分是最后一部份了,左右介紹HTTP和Broswer的機制。