一文走進(jìn) HTTP 與 TCP 協(xié)議
本文轉(zhuǎn)載自微信公眾號(hào)「三分鐘學(xué)前端」,作者sisterAn。轉(zhuǎn)載本文請(qǐng)聯(lián)系三分鐘學(xué)前端公眾號(hào)。
引言
本文從 OSI 網(wǎng)絡(luò)分層(7 層) 開(kāi)始探討 TCP 與 HTTP 的關(guān)系,包含以下幾個(gè)部分:
- OSI 網(wǎng)絡(luò)分層(7 層)
- TCP 協(xié)議(三次握手、四次揮手)
- HTTP
- TCP 與 HTTP 的區(qū)別與聯(lián)系
OSI 網(wǎng)絡(luò)分層(7 層)
Open Systems Interconncection 開(kāi)放系統(tǒng)互聯(lián):
1 物理層 -> 2 數(shù)據(jù)鏈路層 -> 3 網(wǎng)絡(luò)層(ip)-> 4 傳輸層(tcp) -> 5 會(huì)話(huà)層 --> 6 表示層 --> 7 應(yīng)用層(http)
協(xié)議 | 描述 | |
---|---|---|
第七層 | 應(yīng)用層 | 支持網(wǎng)絡(luò)應(yīng)用,應(yīng)用協(xié)議僅僅是網(wǎng)絡(luò)應(yīng)用的一個(gè)組成部分,運(yùn)行在不同主機(jī)上的進(jìn)程則使用應(yīng)用層協(xié)議進(jìn)行通信。主要的協(xié)議有:http、ftp、dns、telnet、smtp、pop3等。 |
第六層 | 表示層 | 把數(shù)據(jù)轉(zhuǎn)換為合適、可理解的語(yǔ)法和語(yǔ)義 |
第五層 | 會(huì)話(huà)層 | 維護(hù)網(wǎng)絡(luò)中的連接狀態(tài),即保持會(huì)話(huà)和同步,有 SSL |
第四層 | 傳輸層 | 負(fù)責(zé)為信源和信宿提供應(yīng)用程序進(jìn)程間的數(shù)據(jù)傳輸服務(wù),這一層上主要定義了兩個(gè)傳輸協(xié)議,即傳輸控制協(xié)議TCP和用戶(hù)數(shù)據(jù)報(bào)協(xié)議UDP。 |
第三層 | 網(wǎng)絡(luò)層 | 負(fù)責(zé)將數(shù)據(jù)報(bào)獨(dú)立地從信源發(fā)送到信宿,主要解決路由選擇、擁塞控制和網(wǎng)絡(luò)互聯(lián)等問(wèn)題。IP 在這一層 |
第二層 | 數(shù)據(jù)鏈路層 | 負(fù)責(zé)將IP數(shù)據(jù)報(bào)封裝成合適在物理網(wǎng)絡(luò)上傳輸?shù)膸袷讲鬏敚驅(qū)奈锢砭W(wǎng)絡(luò)接收到的幀解封,取出IP數(shù)據(jù)報(bào)交給網(wǎng)絡(luò)層。 |
第一層 | 物理層 | 負(fù)責(zé)將比特流在結(jié)點(diǎn)間傳輸,即負(fù)責(zé)物理傳輸。該層的協(xié)議既與鏈路有關(guān)也與傳輸介質(zhì)有關(guān)。 |
HTTP 是應(yīng)用層協(xié)議,而 TCP 是傳輸層協(xié)議,接下來(lái)我們逐一詳細(xì)介紹??
TCP
TCP、UDP都是是傳輸層協(xié)議:
- 用戶(hù)數(shù)據(jù)報(bào)協(xié)議 UDP(User Datagram Protocol):
- 無(wú)連接;
- 盡最大努力的交付;
- 面向報(bào)文;
- 無(wú)擁塞控制;
- 支持一對(duì)一、一對(duì)多、多對(duì)一、多對(duì)多的交互通信;
- 首部開(kāi)銷(xiāo)小(只有四個(gè)字段:源端口、目的端口、長(zhǎng)度、檢驗(yàn)和)。
- 傳輸控制協(xié)議 TCP(Transmission Control Protocol):
- 面向連接;
- 每一個(gè)TCP連接只能是點(diǎn)對(duì)點(diǎn)的(一對(duì)一);
- 提供 可靠交付 服務(wù);
- 提供 全雙工 通信;
- 面向字節(jié)流。
另外,UDP是面向報(bào)文的傳輸方式是應(yīng)用層交給UDP多長(zhǎng)的報(bào)文,UDP發(fā)送多長(zhǎng)的報(bào)文,即一次發(fā)送一個(gè)報(bào)文。因此,應(yīng)用程序必須選擇合適大小的報(bào)文
應(yīng)用程序和 TCP 的交互是一次一個(gè)數(shù)據(jù)塊(大小不等),但 TCP 把應(yīng)用程序看成是一連串的無(wú)結(jié)構(gòu)的字節(jié)流。TCP有一個(gè)緩沖,當(dāng)應(yīng)該程序傳送的數(shù)據(jù)塊太長(zhǎng),TCP就可以把它劃分短一些再傳送
當(dāng)網(wǎng)絡(luò)通信時(shí)采用 TCP 協(xié)議時(shí),在真正的讀寫(xiě)操作之前,客戶(hù)端與服務(wù)器端之間必須建立一個(gè)連接,當(dāng)讀寫(xiě)操作完成后,雙方不再需要這個(gè)連接時(shí)可以釋放這個(gè)連接。連接的建立依靠“三次握手”,而釋放則需要“四次握手”,所以每個(gè)連接的建立都是需要資源消耗和時(shí)間消耗的
TCP連接過(guò)程(三次握手)
第一次握手
客戶(hù)端向服務(wù)端發(fā)送連接請(qǐng)求報(bào)文段。該報(bào)文段中包含自身的數(shù)據(jù)通訊初始序號(hào)。請(qǐng)求發(fā)送后,客戶(hù)端便進(jìn)入 SYN-SENT 狀態(tài)。
第二次握手
服務(wù)端收到連接請(qǐng)求報(bào)文段后,如果同意連接,則會(huì)發(fā)送一個(gè)應(yīng)答,該應(yīng)答中也會(huì)包含自身的數(shù)據(jù)通訊初始序號(hào),發(fā)送完成后便進(jìn)入 SYN-RECEIVED 狀態(tài)。
第三次握手
當(dāng)客戶(hù)端收到連接同意的應(yīng)答后,還要向服務(wù)端發(fā)送一個(gè)確認(rèn)報(bào)文??蛻?hù)端發(fā)完這個(gè)報(bào)文段后便進(jìn)入 ESTABLISHED 狀態(tài),服務(wù)端收到這個(gè)應(yīng)答后也進(jìn)入 ESTABLISHED 狀態(tài),此時(shí)連接建立成功。
為什么需要三次握手,2次不行嗎?
喂喂喂,我是A,你聽(tīng)的到嗎?B:在在在,我能聽(tīng)到,我是B,你能聽(tīng)到我嗎? A:(聽(tīng)到了,老子不想理你) B:喂喂喂?聽(tīng)不聽(tīng)到?我X,對(duì)面死了,我掛了。。
如果只有 2 次的話(huà),B 并不清楚 A 是否收到他發(fā)過(guò)去的信息。
TCP斷開(kāi)鏈接(四次揮手)
第一次揮手
若客戶(hù)端 A 認(rèn)為數(shù)據(jù)發(fā)送完成,則它需要向服務(wù)端 B 發(fā)送連接釋放請(qǐng)求。
第二次揮手
B 收到連接釋放請(qǐng)求后,會(huì)告訴應(yīng)用層要釋放 TCP 鏈接。然后會(huì)發(fā)送 ACK 包,并進(jìn)入 CLOSE_WAIT 狀態(tài),此時(shí)表明 A 到 B 的連接已經(jīng)釋放,不再接收 A 發(fā)的數(shù)據(jù)了。但是因?yàn)?TCP 連接是雙向的,所以 B 仍舊可以發(fā)送數(shù)據(jù)給 A。
第三次揮手
B 如果此時(shí)還有沒(méi)發(fā)完的數(shù)據(jù)會(huì)繼續(xù)發(fā)送,完畢后會(huì)向 A 發(fā)送連接釋放請(qǐng)求,然后 B 便進(jìn)入 LAST-ACK 狀態(tài)。
PS:通過(guò)延遲確認(rèn)的技術(shù)(通常有時(shí)間限制,否則對(duì)方會(huì)誤認(rèn)為需要重傳),可以將第二次和第三次握手合并,延遲 ACK 包的發(fā)送。
第四次揮手
A 收到釋放請(qǐng)求后,向 B 發(fā)送確認(rèn)應(yīng)答,此時(shí) A 進(jìn)入 TIME-WAIT 狀態(tài)。該狀態(tài)會(huì)持續(xù) 2MSL(最長(zhǎng)報(bào)文段壽命,指報(bào)文段在網(wǎng)絡(luò)中生存的時(shí)間,超時(shí)會(huì)被拋棄) 時(shí)間,若該時(shí)間段內(nèi)沒(méi)有 B 的重發(fā)請(qǐng)求的話(huà),就進(jìn)入 CLOSED 狀態(tài)。當(dāng) B 收到確認(rèn)應(yīng)答后,也便進(jìn)入 CLOSED 狀態(tài)。
HTTP
HTTP 是建立在 TCP 上的應(yīng)用層協(xié)議,超文本傳送協(xié)議。
HTTP 連接最顯著的特點(diǎn)是客戶(hù)端發(fā)送的每次請(qǐng)求都需要服務(wù)器回送響應(yīng),在請(qǐng)求結(jié)束后,會(huì)主動(dòng)釋放連接。從建立連接到關(guān)閉連接的過(guò)程稱(chēng)為“一次連接”。
http1.0 :客戶(hù)端的每次請(qǐng)求都要求建立一次單獨(dú)的連接,在處理完本次請(qǐng)求后,就自動(dòng)釋放連接。
http1.1 :可以在一次連接中處理多個(gè)請(qǐng)求,并且多個(gè)請(qǐng)求可以重疊進(jìn)行,不需要等待一個(gè)請(qǐng)求結(jié)束后就可以再發(fā)送一個(gè)新的請(qǐng)求
http2.0 :支持多路復(fù)用,一個(gè) TCP 可同時(shí)傳輸多個(gè) http 請(qǐng)求,頭部數(shù)據(jù)還做了壓縮
http3.0 :使用了 QUIC,開(kāi)啟多個(gè) TCP 連接,在出現(xiàn)丟包的情況下,只有丟包的 TCP 等待重傳,剩余的 TCP 連接還可以正常傳輸數(shù)據(jù)
HTTP特點(diǎn)
- 無(wú)狀態(tài):協(xié)議對(duì)客戶(hù)端沒(méi)有狀態(tài)存儲(chǔ),對(duì)事物處理沒(méi)有“記憶”能力,比如訪問(wèn)一個(gè)網(wǎng)站需要反復(fù)進(jìn)行登錄操作。
- 無(wú)連接:HTTP/1.1之前,由于無(wú)狀態(tài)特點(diǎn),每次請(qǐng)求需要通過(guò)TCP三次握手四次揮手,和服務(wù)器重新建立連接。比如某個(gè)客戶(hù)機(jī)在短時(shí)間多次請(qǐng)求同一個(gè)資源,服務(wù)器并不能區(qū)別是否已經(jīng)響應(yīng)過(guò)用戶(hù)的請(qǐng)求,所以每次需要重新響應(yīng)請(qǐng)求,需要耗費(fèi)不必要的時(shí)間和流量。
- 基于請(qǐng)求和響應(yīng):基本的特性,由客戶(hù)端發(fā)起請(qǐng)求,服務(wù)端響應(yīng)。
- 簡(jiǎn)單快速、靈活。
- 通信使用明文、請(qǐng)求和響應(yīng)不會(huì)對(duì)通信方進(jìn)行確認(rèn)、無(wú)法保護(hù)數(shù)據(jù)的完整性。
Method
- GET 方法請(qǐng)求一個(gè)指定資源的表示形式. 使用GET的請(qǐng)求應(yīng)該只被用于獲取數(shù)據(jù).
- HEAD 方法請(qǐng)求一個(gè)與GET請(qǐng)求的響應(yīng)相同的響應(yīng),只返回請(qǐng)求頭,沒(méi)有響應(yīng)體,多數(shù)由 JavaScript 發(fā)起
- POST 方法用于將實(shí)體提交到指定的資源,通常導(dǎo)致?tīng)顟B(tài)或服務(wù)器上的副作用的更改.
- PUT 方法用請(qǐng)求有效載荷替換目標(biāo)資源的所有當(dāng)前表示。
- DELETE 方法刪除指定的資源。
- CONNECT 方法建立一個(gè)到由目標(biāo)資源標(biāo)識(shí)的服務(wù)器的隧道,多用于 HTTPS 和 WebSocket 。
- OPTIONS 方法,預(yù)檢,用于描述目標(biāo)資源的通信選項(xiàng)。通過(guò)該請(qǐng)求來(lái)知道服務(wù)端是否允許跨域請(qǐng)求。
- TRACE 方法沿著到目標(biāo)資源的路徑執(zhí)行一個(gè)消息環(huán)回測(cè)試,多數(shù)線上服務(wù)都不支持
- PATCH 方法用于對(duì)資源應(yīng)用部分修改。
HTTP 與 TCP 區(qū)別
TCP 協(xié)議對(duì)應(yīng)于傳輸層,而 HTTP 協(xié)議對(duì)應(yīng)于應(yīng)用層,從本質(zhì)上來(lái)說(shuō),二者沒(méi)有可比性:
- HTTP 對(duì)應(yīng)于應(yīng)用層,TCP 協(xié)議對(duì)應(yīng)于傳輸層
- HTTP 協(xié)議是在 TCP 協(xié)議之上建立的,HTTP 在發(fā)起請(qǐng)求時(shí)通過(guò) TCP 協(xié)議建立起連接服務(wù)器的通道,請(qǐng)求結(jié)束后,立即斷開(kāi) TCP 連接
- HTTP 是無(wú)狀態(tài)的短連接,而 TCP 是有狀態(tài)的長(zhǎng)連接
- TCP是傳輸層協(xié)議,定義的是數(shù)據(jù)傳輸和連接方式的規(guī)范,HTTP是應(yīng)用層協(xié)議,定義的是傳輸數(shù)據(jù)的內(nèi)容的規(guī)范
說(shuō)明:從HTTP/1.1起,默認(rèn)都開(kāi)啟了Keep-Alive,保持連接特性,簡(jiǎn)單地說(shuō),當(dāng)一個(gè)網(wǎng)頁(yè)打開(kāi)完成后,客戶(hù)端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接不會(huì)關(guān)閉,如果客戶(hù)端再次訪問(wèn)這個(gè)服務(wù)器上的網(wǎng)頁(yè),會(huì)繼續(xù)使用這一條已經(jīng)建立的連接Keep-Alive不會(huì)永久保持連接,它有一個(gè)保持時(shí)間,可以在不同的服務(wù)器軟件(如Apache)中設(shè)定這個(gè)時(shí)間。
來(lái)自:https://github.com/Advanced-Frontend/Daily-Interview-Question