負責域名解析的DNS 服務
首先,用戶訪問一個域名,會經過 DNS 解析DNS(Domain Name System),它和 HTTP 協議一樣是位于應用層的協議,主要提供域名到IP 的解析服務。我們其實不用域名也可以訪問目標主機的服務,但是 IP 本身不是那么容易記,所以使用域名進行替換使得用戶更容易記住。
HTTP 協議通信原理
域名被成功解析以后,客戶端和服務端之間,是怎么建立連接并且如何通信的呢?說到通信,大家一定聽過 tcp 和 udp 這兩種通信協議,以及建立連接的握手過程。而 http 協議的通信是基于 tcp/ip 協議之上的一個應用層協議,應用層協議除了 http 還有哪些呢(FTP、DNS、SMTP、Telnet 等)。
涉及到網絡協議,我們一定需要知道 OSI 七層網絡模型和 TCP/IP 四層概念模型,OSI 七層網絡模型包含(應用層、表示層、會話層、傳輸層、網絡層、數據鏈路層、物理層)、TCP/IP 四層概念模型包含(應用層、傳輸層、網絡層、數據鏈路層)。
請求發起過程中,在 tcp/ip 四層網絡模型中所做的事情
當應用程序用 T C P 傳送數據時,數據被送入協議棧中,然后逐個通過每一層直到被當作一串比特流送入網絡。其中每一層對收到的數據都要增加一些首部信息(有時還要增加尾部信息)
接收端收到數據包以后的處理過程
當目的主機收到一個以太網數據幀時,數據就開始從協議棧中由底向上升,同時去掉各層協議加上的報文首部。每層協議都要去檢查報文首部中的協議標識,以確定接收數據的上層協議。
TCP/IP 協議的深入分析
TCP 握手協議
所以 TCP 消息的可靠性首先來自于有效的連接建立,所以在數據進行傳輸前,需要通過三次握手建立一個連接,所謂的三次握手,就是在建立 TCP 鏈接時,需要客戶端和服務端總共發送 3 個包來確認連接的建立,在 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 發完畢后 , 客 戶 端 進 入ESTABLISHED 狀態,當服務器端接收到這個包時,也進 入ESTABLISHED 狀態,TCP 握手結束。
TCP 四次揮手協議
四次揮手表示 TCP 斷開連接的時候,需要客戶端和服務端總共發送 4 個包以確認連接的斷開;客戶端或服務器均可主動發起揮手動作(因為 TCP 是一個全雙工協議),在 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=w)服務器端準備好關閉連接時,向客戶端發送結束連接請求,FIN 置為 1。發送完畢后,服務器端進入 LAST_ACK 狀態,等待來自客戶端的最后一個 ACK。
第四次揮手(ACK=1,ACKnum=w+1)客戶端接收到來自服務器端的關閉請求,發送一個確認包,并進入 TIME_WAIT 狀態,等待可能出現的要求重傳的 ACK 包。服務器端接收到這個確認包之后,關閉連接,進入 CLOSED 狀態。客戶端等待了某個固定時間(兩個最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,沒有收到服務器端的 ACK,認為服務器端已經正常關閉連接,于是自己也關閉連接,進入 CLOSED 狀態。
假設 Client 端發起中斷連接請求,也就是發送 FIN 報文。Server 端接到 FIN 報文后,意思是說"我 Client 端沒有數據要發給你了",但是如果你還有數據沒有發送完成,則不必急著關閉Socket,可以繼續發送數據。所以你先發送 ACK,"告訴 Client 端,你的請求我收到了,但是我還沒準備好,請繼續你等我的消息"。這個時候 Client 端就進入 FIN_WAIT 狀態,繼續等待Server 端的 FIN 報文。當 Server 端確定數據已發送完成,則向 Client 端發送 FIN 報文,"告訴 Client 端,好了,我這邊數據發完了,準備好關閉連接了"。Client 端收到 FIN 報文后,"就知道可以關閉連接了,但是他還是不相信網絡,怕 Server 端不知道要關閉,所以發送 ACK 后進入 TIME_WAIT 狀態,如果 Server 端沒有收到 ACK 則可以重傳。“,Server 端收到 ACK 后,"就知道可以斷開連接了"。Client 端等待了 2MSL 后依然沒有收到回復,則證明 Server 端已正常關閉,那好,我 Client 端也可以關閉連接了。Ok,TCP 連接就這樣關閉了!
【問題 1】為什么連接的時候是三次握手,關閉的時候卻是四次握手?
答:三次握手是因為因為當 Server 端收到 Client 端的 SYN 連接請求報文后,可以直接發送SYN+ACK 報文。其中 ACK 報文是用來應答的,SYN 報文是用來同步的。但是關閉連接時,當 Server 端收到 FIN 報文時,很可能并不會立即關閉 SOCKET(因為可能還有消息沒處理完),所以只能先回復一個 ACK 報文,告訴 Client 端,"你發的 FIN 報文我收到了"。只有等到我 Server 端所有的報文都發送完了,我才能發送 FIN 報文,因此不能一起發送。故需要四步握手。






