負(fù)責(zé)域名解析的DNS 服務(wù)
首先,用戶訪問一個域名,會經(jīng)過 DNS 解析DNS(Domain Name System),它和 HTTP 協(xié)議一樣是位于應(yīng)用層的協(xié)議,主要提供域名到IP 的解析服務(wù)。我們其實不用域名也可以訪問目標(biāo)主機的服務(wù),但是 IP 本身不是那么容易記,所以使用域名進行替換使得用戶更容易記住。
HTTP 協(xié)議通信原理
域名被成功解析以后,客戶端和服務(wù)端之間,是怎么建立連接并且如何通信的呢?說到通信,大家一定聽過 tcp 和 udp 這兩種通信協(xié)議,以及建立連接的握手過程。而 http 協(xié)議的通信是基于 tcp/ip 協(xié)議之上的一個應(yīng)用層協(xié)議,應(yīng)用層協(xié)議除了 http 還有哪些呢(FTP、DNS、SMTP、Telnet 等)。
涉及到網(wǎng)絡(luò)協(xié)議,我們一定需要知道 OSI 七層網(wǎng)絡(luò)模型和 TCP/IP 四層概念模型,OSI 七層網(wǎng)絡(luò)模型包含(應(yīng)用層、表示層、會話層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層、物理層)、TCP/IP 四層概念模型包含(應(yīng)用層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層)。
請求發(fā)起過程中,在 tcp/ip 四層網(wǎng)絡(luò)模型中所做的事情
當(dāng)應(yīng)用程序用 T C P 傳送數(shù)據(jù)時,數(shù)據(jù)被送入?yún)f(xié)議棧中,然后逐個通過每一層直到被當(dāng)作一串比特流送入網(wǎng)絡(luò)。其中每一層對收到的數(shù)據(jù)都要增加一些首部信息(有時還要增加尾部信息)
接收端收到數(shù)據(jù)包以后的處理過程
當(dāng)目的主機收到一個以太網(wǎng)數(shù)據(jù)幀時,數(shù)據(jù)就開始從協(xié)議棧中由底向上升,同時去掉各層協(xié)議加上的報文首部。每層協(xié)議都要去檢查報文首部中的協(xié)議標(biāo)識,以確定接收數(shù)據(jù)的上層協(xié)議。
TCP/IP 協(xié)議的深入分析
TCP 握手協(xié)議
所以 TCP 消息的可靠性首先來自于有效的連接建立,所以在數(shù)據(jù)進行傳輸前,需要通過三次握手建立一個連接,所謂的三次握手,就是在建立 TCP 鏈接時,需要客戶端和服務(wù)端總共發(fā)送 3 個包來確認(rèn)連接的建立,在 socket 編程中,這個過程由客戶端執(zhí)行 connect 來觸發(fā)
第 一 次 握 手(SYN=1, seq=x)客 戶 端 發(fā) 送 一 個TCP 的 SYN 標(biāo)志位置 1 的包,指明客戶端打算連接的服務(wù)器的端口,以及初始序號 X ,保存在 包 頭 的 序 列 號(Sequence
Number)字段里 。發(fā)送完畢后,客戶端 進 入SYN_SEND 狀態(tài)。
第 二 次 握 手(SYN=1, ACK=1,seq=y,ACKnum=x+1):服務(wù)器發(fā)回確認(rèn)包(ACK) 應(yīng) 答 。 即SYN 標(biāo) 志 位 和ACK 標(biāo)志位均為1。服務(wù)器端選擇自己 ISN 序列號,放到 Seq 域里,同時將 確 認(rèn) 序 號(Acknowledgement Number)設(shè)置為客戶的 ISN 加 1,即 X+1。發(fā)送完畢后,服務(wù)器 端 進 入SYN_RCVD 狀態(tài)。
第 三 次 握 手(ACK=1 ,ACKnum=y+1)客戶端再次發(fā)送確認(rèn)包(ACK),SYN 標(biāo)志位為 0,ACK 標(biāo)志位為 1,并且把服務(wù)器發(fā)來 ACK 的序號字段+1,放在確定字段中發(fā)送給對方,并且在數(shù)據(jù)段放寫 ISN 發(fā)完畢后 , 客 戶 端 進 入ESTABLISHED 狀態(tài),當(dāng)服務(wù)器端接收到這個包時,也進 入ESTABLISHED 狀態(tài),TCP 握手結(jié)束。
TCP 四次揮手協(xié)議
四次揮手表示 TCP 斷開連接的時候,需要客戶端和服務(wù)端總共發(fā)送 4 個包以確認(rèn)連接的斷開;客戶端或服務(wù)器均可主動發(fā)起揮手動作(因為 TCP 是一個全雙工協(xié)議),在 socket 編程中,任何一方執(zhí)行 close() 操作即可產(chǎn)生揮手操作。
第一次揮手(FIN=1,seq=x)假設(shè)客戶端想要關(guān)閉連接,客戶端發(fā)送一個 FIN 標(biāo)志位置為 1 的包,表示自己已經(jīng)沒有數(shù)據(jù)可以發(fā)送了,但是仍然可以接受數(shù)據(jù)。發(fā)送完畢后,客戶端進入 FIN_WAIT_1 狀態(tài)。
第二次揮手(ACK=1,ACKnum=x+1)服務(wù)器端確認(rèn)客戶端的 FIN 包,發(fā)送一個確認(rèn)包,表明自己接受到了客戶端關(guān)閉連接的請求,但還沒有準(zhǔn)備好關(guān)閉連接。發(fā)送完畢后,服務(wù)器端進入 CLOSE_WAIT 狀態(tài),客戶端接收到這個確認(rèn)包之后,進入 FIN_WAIT_2 狀態(tài),等待服務(wù)器端關(guān)閉連接。
第三次揮手(FIN=1,seq=w)服務(wù)器端準(zhǔn)備好關(guān)閉連接時,向客戶端發(fā)送結(jié)束連接請求,F(xiàn)IN 置為 1。發(fā)送完畢后,服務(wù)器端進入 LAST_ACK 狀態(tài),等待來自客戶端的最后一個 ACK。
第四次揮手(ACK=1,ACKnum=w+1)客戶端接收到來自服務(wù)器端的關(guān)閉請求,發(fā)送一個確認(rèn)包,并進入 TIME_WAIT 狀態(tài),等待可能出現(xiàn)的要求重傳的 ACK 包。服務(wù)器端接收到這個確認(rèn)包之后,關(guān)閉連接,進入 CLOSED 狀態(tài)。客戶端等待了某個固定時間(兩個最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,沒有收到服務(wù)器端的 ACK,認(rèn)為服務(wù)器端已經(jīng)正常關(guān)閉連接,于是自己也關(guān)閉連接,進入 CLOSED 狀態(tài)。
假設(shè) Client 端發(fā)起中斷連接請求,也就是發(fā)送 FIN 報文。Server 端接到 FIN 報文后,意思是說"我 Client 端沒有數(shù)據(jù)要發(fā)給你了",但是如果你還有數(shù)據(jù)沒有發(fā)送完成,則不必急著關(guān)閉Socket,可以繼續(xù)發(fā)送數(shù)據(jù)。所以你先發(fā)送 ACK,"告訴 Client 端,你的請求我收到了,但是我還沒準(zhǔn)備好,請繼續(xù)你等我的消息"。這個時候 Client 端就進入 FIN_WAIT 狀態(tài),繼續(xù)等待Server 端的 FIN 報文。當(dāng) Server 端確定數(shù)據(jù)已發(fā)送完成,則向 Client 端發(fā)送 FIN 報文,"告訴 Client 端,好了,我這邊數(shù)據(jù)發(fā)完了,準(zhǔn)備好關(guān)閉連接了"。Client 端收到 FIN 報文后,"就知道可以關(guān)閉連接了,但是他還是不相信網(wǎng)絡(luò),怕 Server 端不知道要關(guān)閉,所以發(fā)送 ACK 后進入 TIME_WAIT 狀態(tài),如果 Server 端沒有收到 ACK 則可以重傳。“,Server 端收到 ACK 后,"就知道可以斷開連接了"。Client 端等待了 2MSL 后依然沒有收到回復(fù),則證明 Server 端已正常關(guān)閉,那好,我 Client 端也可以關(guān)閉連接了。Ok,TCP 連接就這樣關(guān)閉了!
【問題 1】為什么連接的時候是三次握手,關(guān)閉的時候卻是四次握手?
答:三次握手是因為因為當(dāng) Server 端收到 Client 端的 SYN 連接請求報文后,可以直接發(fā)送SYN+ACK 報文。其中 ACK 報文是用來應(yīng)答的,SYN 報文是用來同步的。但是關(guān)閉連接時,當(dāng) Server 端收到 FIN 報文時,很可能并不會立即關(guān)閉 SOCKET(因為可能還有消息沒處理完),所以只能先回復(fù)一個 ACK 報文,告訴 Client 端,"你發(fā)的 FIN 報文我收到了"。只有等到我 Server 端所有的報文都發(fā)送完了,我才能發(fā)送 FIN 報文,因此不能一起發(fā)送。故需要四步握手。