前端面試 計算機網(wǎng)絡(luò)篇

2023-02-17 10:51 更新


一、HTTP協(xié)議


1. GET和POST的請求的區(qū)別

Post 和 Get 是 HTTP 請求的兩種方法,其區(qū)別如下:

  • 應(yīng)用場景:GET 請求是一個冪等的請求,一般 Get 請求用于對服務(wù)器資源不會產(chǎn)生影響的場景,比如說請求一個網(wǎng)頁的資源。而 Post 不是一個冪等的請求,一般用于對服務(wù)器資源會產(chǎn)生影響的情景,比如注冊用戶這一類的操作。
  • 是否緩存:因為兩者應(yīng)用場景不同,瀏覽器一般會對 Get 請求緩存,但很少對 Post 請求緩存。
  • 發(fā)送的報文格式:Get 請求的報文中實體部分為空,Post 請求的報文中實體部分一般為向服務(wù)器發(fā)送的數(shù)據(jù)。
  • 安全性:Get 請求可以將請求的參數(shù)放入 url 中向服務(wù)器發(fā)送,這樣的做法相對于 Post 請求來說是不太安全的,因為請求的 url 會被保留在歷史記錄中。
  • 請求長度:瀏覽器由于對 url 長度的限制,所以會影響 get 請求發(fā)送數(shù)據(jù)時的長度。這個限制是瀏覽器規(guī)定的,并不是 RFC 規(guī)定的。
  • 參數(shù)類型:post 的參數(shù)傳遞支持更多的數(shù)據(jù)類型。

2. POST和PUT請求的區(qū)別

  • PUT請求是向服務(wù)器端發(fā)送數(shù)據(jù),從而修改數(shù)據(jù)的內(nèi)容,但是不會增加數(shù)據(jù)的種類等,也就是說無論進行多少次PUT操作,其結(jié)果并沒有不同。(可以理解為是更新數(shù)據(jù)
  • POST請求是向服務(wù)器端發(fā)送數(shù)據(jù),該請求會改變數(shù)據(jù)的種類等資源,它會創(chuàng)建新的內(nèi)容。(可以理解為是創(chuàng)建數(shù)據(jù)

3. 常見的HTTP請求頭和響應(yīng)頭

HTTP Request Header 常見的請求頭:

  • Accept:瀏覽器能夠處理的內(nèi)容類型
  • Accept-Charset:瀏覽器能夠顯示的字符集
  • Accept-Encoding:瀏覽器能夠處理的壓縮編碼
  • Accept-Language:瀏覽器當(dāng)前設(shè)置的語言
  • Connection:瀏覽器與服務(wù)器之間連接的類型
  • Cookie:當(dāng)前頁面設(shè)置的任何Cookie
  • Host:發(fā)出請求的頁面所在的域
  • Referer:發(fā)出請求的頁面的URL
  • User-Agent:瀏覽器的用戶代理字符串

HTTP Responses Header 常見的響應(yīng)頭:

  • Date:表示消息發(fā)送的時間,時間的描述格式由rfc822定義
  • server:服務(wù)器名稱
  • Connection:瀏覽器與服務(wù)器之間連接的類型
  • Cache-Control:控制HTTP緩存
  • content-type:表示后面的文檔屬于什么MIME類型

常見的 Content-Type 屬性值有以下四種:

(1)application/x-www-form-urlencoded:瀏覽器的原生 form 表單,如果不設(shè)置 enctype 屬性,那么最終就會以 application/x-www-form-urlencoded 方式提交數(shù)據(jù)。該種方式提交的數(shù)據(jù)放在 body 里面,數(shù)據(jù)按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL轉(zhuǎn)碼。

(2)multipart/form-data:該種方式也是一個常見的 POST 提交方式,通常表單上傳文件時使用該種方式。

(3)application/json:服務(wù)器消息主體是序列化后的 JSON 字符串。

(4)text/xml:該種方式主要用來提交 XML 格式的數(shù)據(jù)。

服務(wù)器向客戶端發(fā)送數(shù)據(jù)格式類型:XML、HTML、JSON

4. HTTP狀態(tài)碼304是多好還是少好

服務(wù)器為了提高網(wǎng)站訪問速度,對之前訪問的部分頁面指定緩存機制,當(dāng)客戶端在此對這些頁面進行請求,服務(wù)器會根據(jù)緩存內(nèi)容判斷頁面與之前是否相同,若相同便直接返回304,此時客戶端調(diào)用緩存內(nèi)容,不必進行二次下載。

狀態(tài)碼304不應(yīng)該認為是一種錯誤,而是對客戶端有緩存情況下服務(wù)端的一種響應(yīng)。

搜索引擎蜘蛛會更加青睞內(nèi)容源更新頻繁的網(wǎng)站。通過特定時間內(nèi)對網(wǎng)站抓取返回的狀態(tài)碼來調(diào)節(jié)對該網(wǎng)站的抓取頻次。若網(wǎng)站在一定時間內(nèi)一直處于304的狀態(tài),那么蜘蛛可能會降低對網(wǎng)站的抓取次數(shù)。相反,若網(wǎng)站變化的頻率非常之快,每次抓取都能獲取新內(nèi)容,那么日積月累,的回訪率也會提高。

產(chǎn)生較多304狀態(tài)碼的原因:

  • 頁面更新周期長或不更新
  • 純靜態(tài)頁面或強制生成靜態(tài)html

304狀態(tài)碼出現(xiàn)過多會造成以下問題:

  • 網(wǎng)站快照停止;
  • 收錄減少;
  • 權(quán)重下降。

5. 常見的HTTP請求方法

  • GET: 向服務(wù)器獲取數(shù)據(jù);
  • POST:將實體提交到指定的資源,通常會造成服務(wù)器資源的修改;
  • PUT:上傳文件,更新數(shù)據(jù);
  • DELETE:刪除服務(wù)器上的對象;
  • HEAD:獲取報文首部,與GET相比,不返回報文主體部分;
  • OPTIONS:詢問支持的請求方法,用來跨域請求;
  • CONNECT:要求在與代理服務(wù)器通信時建立隧道,使用隧道進行TCP通信;
  • TRACE: 回顯服務(wù)器收到的請求,主要?于測試或診斷。

6. OPTIONS請求方法及使用場景

OPTIONS是除了GET和POST之外的其中一種 HTTP請求方法。

OPTIONS方法是用于請求獲得由 Request-URI標(biāo)識的資源在請求/響應(yīng)的通信過程中可以使用的功能選項。通過這個方法,客戶端可以在采取具體資源請求之前,決定對該資源采取何種必要措施,或者了解服務(wù)器的性能。該請求方法的響應(yīng)不能緩存。

OPTIONS請求方法的主要用途有兩個:

  • 獲取服務(wù)器支持的所有HTTP請求方法;
  • 用來檢查訪問權(quán)限。例如:在進行 CORS 跨域資源共享時,對于復(fù)雜請求,就是使用 OPTIONS 方法發(fā)送嗅探請求,以判斷是否有對指定資源的訪問權(quán)限。

7. HTTP 1.0 和 HTTP 1.1 之間有哪些區(qū)別?

HTTP 1.0和 HTTP 1.1 有以下區(qū)別

  • 連接方面,http1.0 默認使用非持久連接,而 http1.1 默認使用持久連接。http1.1 通過使用持久連接來使多個 http 請求復(fù)用同一個 TCP 連接,以此來避免使用非持久連接時每次需要建立連接的時延。
  • 資源請求方面,在 http1.0 中,存在一些浪費帶寬的現(xiàn)象,例如客戶端只是需要某個對象的一部分,而服務(wù)器卻將整個對象送過來了,并且不支持?jǐn)帱c續(xù)傳功能,http1.1 則在請求頭引入了 range 頭域,它允許只請求資源的某個部分,即返回碼是 206(Partial Content),這樣就方便了開發(fā)者自由的選擇以便于充分利用帶寬和連接。
  • 緩存方面,在 http1.0 中主要使用 header 里的 If-Modified-Since、Expires 來做為緩存判斷的標(biāo)準(zhǔn),http1.1 則引入了更多的緩存控制策略,例如 Etag、If-Unmodified-Since、If-Match、If-None-Match 等更多可供選擇的緩存頭來控制緩存策略。
  • http1.1 中新增了 host 字段,用來指定服務(wù)器的域名。http1.0 中認為每臺服務(wù)器都綁定一個唯一的 IP 地址,因此,請求消息中的 URL 并沒有傳遞主機名(hostname)。但隨著虛擬主機技術(shù)的發(fā)展,在一臺物理服務(wù)器上可以存在多個虛擬主機,并且它們共享一個IP地址。因此有了 host 字段,這樣就可以將請求發(fā)往到同一臺服務(wù)器上的不同網(wǎng)站。
  • http1.1 相對于 http1.0 還新增了很多請求方法,如 PUT、HEAD、OPTIONS 等。

8. HTTP 1.1 和 HTTP 2.0 的區(qū)別

  • 二進制協(xié)議:HTTP/2 是一個二進制協(xié)議。在 HTTP/1.1 版中,報文的頭信息必須是文本(ASCII 編碼),數(shù)據(jù)體可以是文本,也可以是二進制。HTTP/2 則是一個徹底的二進制協(xié)議,頭信息和數(shù)據(jù)體都是二進制,并且統(tǒng)稱為"幀",可以分為頭信息幀和數(shù)據(jù)幀。 幀的概念是它實現(xiàn)多路復(fù)用的基礎(chǔ)。
  • 多路復(fù)用:HTTP/2 實現(xiàn)了多路復(fù)用,HTTP/2 仍然復(fù)用 TCP 連接,但是在一個連接里,客戶端和服務(wù)器都可以同時發(fā)送多個請求或回應(yīng),而且不用按照順序一一發(fā)送,這樣就避免了"隊頭堵塞"【1】的問題。
  • 數(shù)據(jù)流:HTTP/2 使用了數(shù)據(jù)流的概念,因為 HTTP/2 的數(shù)據(jù)包是不按順序發(fā)送的,同一個連接里面連續(xù)的數(shù)據(jù)包,可能屬于不同的請求。因此,必須要對數(shù)據(jù)包做標(biāo)記,指出它屬于哪個請求。HTTP/2 將每個請求或回應(yīng)的所有數(shù)據(jù)包,稱為一個數(shù)據(jù)流。每個數(shù)據(jù)流都有一個獨一無二的編號。數(shù)據(jù)包發(fā)送時,都必須標(biāo)記數(shù)據(jù)流 ID ,用來區(qū)分它屬于哪個數(shù)據(jù)流。
  • 頭信息壓縮:HTTP/2 實現(xiàn)了頭信息壓縮,由于 HTTP 1.1 協(xié)議不帶狀態(tài),每次請求都必須附上所有信息。所以,請求的很多字段都是重復(fù)的,比如 Cookie 和 User Agent ,一模一樣的內(nèi)容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。HTTP/2 對這一點做了優(yōu)化,引入了頭信息壓縮機制。一方面,頭信息使用 gzip 或 compress 壓縮后再發(fā)送;另一方面,客戶端和服務(wù)器同時維護一張頭信息表,所有字段都會存入這個表,生成一個索引號,以后就不發(fā)送同樣字段了,只發(fā)送索引號,這樣就能提高速度了。
  • 服務(wù)器推送:HTTP/2 允許服務(wù)器未經(jīng)請求,主動向客戶端發(fā)送資源,這叫做服務(wù)器推送。使用服務(wù)器推送提前給客戶端推送必要的資源,這樣就可以相對減少一些延遲時間。這里需要注意的是 http2 下服務(wù)器主動推送的是靜態(tài)資源,和 WebSocket 以及使用 SSE 等方式向客戶端發(fā)送即時數(shù)據(jù)的推送是不同的。

【1】隊頭堵塞:

隊頭阻塞是由 HTTP 基本的“請求 - 應(yīng)答”模型所導(dǎo)致的。HTTP 規(guī)定報文必須是“一發(fā)一收”,這就形成了一個先進先出的“串行”隊列。隊列里的請求是沒有優(yōu)先級的,只有入隊的先后順序,排在最前面的請求會被最優(yōu)先處理。如果隊首的請求因為處理的太慢耽誤了時間,那么隊列里后面的所有請求也不得不跟著一起等待,結(jié)果就是其他的請求承擔(dān)了不應(yīng)有的時間成本,造成了隊頭堵塞的現(xiàn)象。

9. HTTP和HTTPS協(xié)議的區(qū)別

HTTP和HTTPS協(xié)議的主要區(qū)別如下:

  • HTTPS協(xié)議需要CA證書,費用較高;而HTTP協(xié)議不需要;
  • HTTP協(xié)議是超文本傳輸協(xié)議,信息是明文傳輸?shù)?,HTTPS則是具有安全性的SSL加密傳輸協(xié)議;
  • 使用不同的連接方式,端口也不同,HTTP協(xié)議端口是80,HTTPS協(xié)議端口是443;
  • HTTP協(xié)議連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是有SSL和HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認證的網(wǎng)絡(luò)協(xié)議,比HTTP更加安全。

10. GET方法URL長度限制的原因

實際上HTTP協(xié)議規(guī)范并沒有對get方法請求的url長度進行限制,這個限制是特定的瀏覽器及服務(wù)器對它的限制。

IE對URL長度的限制是2083字節(jié)(2K+35)。由于IE瀏覽器對URL長度的允許值是最小的,所以開發(fā)過程中,只要URL不超過2083字節(jié),那么在所有瀏覽器中工作都不會有問題。

GET的長度值 = URL(2083)- (你的Domain+Path)-2(2是get請求中?=兩個字符的長度)

下面看一下主流瀏覽器對get方法中url的長度限制范圍:

  • Microsoft Internet Explorer (Browser):IE瀏覽器對URL的最大限制為2083個字符,如果超過這個數(shù)字,提交按鈕沒有任何反應(yīng)。
  • Firefox (Browser):對于Firefox瀏覽器URL的長度限制為 65,536 個字符。
  • Safari (Browser):URL最大長度限制為 80,000 個字符。
  • Opera (Browser):URL最大長度限制為 190,000 個字符。
  • Google (chrome):URL最大長度限制為 8182 個字符。

主流的服務(wù)器對get方法中url的長度限制范圍:

  • Apache (Server):能接受最大url長度為8192個字符。
  • Microsoft Internet Information Server(IIS):能接受最大url的長度為16384個字符。

根據(jù)上面的數(shù)據(jù),可以知道,get方法中的URL長度最長不超過2083個字符,這樣所有的瀏覽器和服務(wù)器都可能正常工作。

11. 當(dāng)在瀏覽器中輸入 Google.com 并且按下回車之后發(fā)生了什么?

(1)解析URL:首先會對 URL 進行解析,分析所需要使用的傳輸協(xié)議和請求的資源的路徑。如果輸入的 URL 中的協(xié)議或者主機名不合法,將會把地址欄中輸入的內(nèi)容傳遞給搜索引擎。如果沒有問題,瀏覽器會檢查 URL 中是否出現(xiàn)了非法字符,如果存在非法字符,則對非法字符進行轉(zhuǎn)義后再進行下一過程。

(2)緩存判斷:瀏覽器會判斷所請求的資源是否在緩存里,如果請求的資源在緩存里并且沒有失效,那么就直接使用,否則向服務(wù)器發(fā)起新的請求。

(3)DNS解析:下一步首先需要獲取的是輸入的 URL 中的域名的 IP 地址,首先會判斷本地是否有該域名的 IP 地址的緩存,如果有則使用,如果沒有則向本地 DNS 服務(wù)器發(fā)起請求。本地 DNS 服務(wù)器也會先檢查是否存在緩存,如果沒有就會先向根域名服務(wù)器發(fā)起請求,獲得負責(zé)的頂級域名服務(wù)器的地址后,再向頂級域名服務(wù)器請求,然后獲得負責(zé)的權(quán)威域名服務(wù)器的地址后,再向權(quán)威域名服務(wù)器發(fā)起請求,最終獲得域名的 IP 地址后,本地 DNS 服務(wù)器再將這個 IP 地址返回給請求的用戶。用戶向本地 DNS 服務(wù)器發(fā)起請求屬于遞歸請求,本地 DNS 服務(wù)器向各級域名服務(wù)器發(fā)起請求屬于迭代請求。

(4)獲取MAC地址:當(dāng)瀏覽器得到 IP 地址后,數(shù)據(jù)傳輸還需要知道目的主機 MAC 地址,因為應(yīng)用層下發(fā)數(shù)據(jù)給傳輸層,TCP 協(xié)議會指定源端口號和目的端口號,然后下發(fā)給網(wǎng)絡(luò)層。網(wǎng)絡(luò)層會將本機地址作為源地址,獲取的 IP 地址作為目的地址。然后將下發(fā)給數(shù)據(jù)鏈路層,數(shù)據(jù)鏈路層的發(fā)送需要加入通信雙方的 MAC 地址,本機的 MAC 地址作為源 MAC 地址,目的 MAC 地址需要分情況處理。通過將 IP 地址與本機的子網(wǎng)掩碼相與,可以判斷是否與請求主機在同一個子網(wǎng)里,如果在同一個子網(wǎng)里,可以使用 ARP 協(xié)議獲取到目的主機的 MAC 地址,如果不在一個子網(wǎng)里,那么請求應(yīng)該轉(zhuǎn)發(fā)給網(wǎng)關(guān),由它代為轉(zhuǎn)發(fā),此時同樣可以通過 ARP 協(xié)議來獲取網(wǎng)關(guān)的 MAC 地址,此時目的主機的 MAC 地址應(yīng)該為網(wǎng)關(guān)的地址。

(5)TCP三次握手:下面是 TCP 建立連接的三次握手的過程,首先客戶端向服務(wù)器發(fā)送一個 SYN 連接請求報文段和一個隨機序號,服務(wù)端接收到請求后向服務(wù)器端發(fā)送一個 SYN ACK報文段,確認連接請求,并且也向客戶端發(fā)送一個隨機序號??蛻舳私邮辗?wù)器的確認應(yīng)答后,進入連接建立的狀態(tài),同時向服務(wù)器也發(fā)送一個ACK 確認報文段,服務(wù)器端接收到確認后,也進入連接建立狀態(tài),此時雙方的連接就建立起來了。

(6)HTTPS握手:如果使用的是 HTTPS 協(xié)議,在通信前還存在 TLS 的一個四次握手的過程。首先由客戶端向服務(wù)器端發(fā)送使用的協(xié)議的版本號、一個隨機數(shù)和可以使用的加密方法。服務(wù)器端收到后,確認加密的方法,也向客戶端發(fā)送一個隨機數(shù)和自己的數(shù)字證書??蛻舳耸盏胶?,首先檢查數(shù)字證書是否有效,如果有效,則再生成一個隨機數(shù),并使用證書中的公鑰對隨機數(shù)加密,然后發(fā)送給服務(wù)器端,并且還會提供一個前面所有內(nèi)容的 hash 值供服務(wù)器端檢驗。服務(wù)器端接收后,使用自己的私鑰對數(shù)據(jù)解密,同時向客戶端發(fā)送一個前面所有內(nèi)容的 hash 值供客戶端檢驗。這個時候雙方都有了三個隨機數(shù),按照之前所約定的加密方法,使用這三個隨機數(shù)生成一把秘鑰,以后雙方通信前,就使用這個秘鑰對數(shù)據(jù)進行加密后再傳輸。

(7)返回數(shù)據(jù):當(dāng)頁面請求發(fā)送到服務(wù)器端后,服務(wù)器端會返回一個 html 文件作為響應(yīng),瀏覽器接收到響應(yīng)后,開始對 html 文件進行解析,開始頁面的渲染過程。

(8)頁面渲染:瀏覽器首先會根據(jù) html 文件構(gòu)建 DOM 樹,根據(jù)解析到的 css 文件構(gòu)建 CSSOM 樹,如果遇到 script 標(biāo)簽,則判端是否含有 defer 或者 async 屬性,要不然 script 的加載和執(zhí)行會造成頁面的渲染的阻塞。當(dāng) DOM 樹和 CSSOM 樹建立好后,根據(jù)它們來構(gòu)建渲染樹。渲染樹構(gòu)建好后,會根據(jù)渲染樹來進行布局。布局完成后,最后使用瀏覽器的 UI 接口對頁面進行繪制。這個時候整個頁面就顯示出來了。

(9)TCP四次揮手:最后一步是 TCP 斷開連接的四次揮手過程。若客戶端認為數(shù)據(jù)發(fā)送完成,則它需要向服務(wù)端發(fā)送連接釋放請求。服務(wù)端收到連接釋放請求后,會告訴應(yīng)用層要釋放 TCP 鏈接。然后會發(fā)送 ACK 包,并進入 CLOSE_WAIT 狀態(tài),此時表明客戶端到服務(wù)端的連接已經(jīng)釋放,不再接收客戶端發(fā)的數(shù)據(jù)了。但是因為 TCP 連接是雙向的,所以服務(wù)端仍舊可以發(fā)送數(shù)據(jù)給客戶端。服務(wù)端如果此時還有沒發(fā)完的數(shù)據(jù)會繼續(xù)發(fā)送,完畢后會向客戶端發(fā)送連接釋放請求,然后服務(wù)端便進入 LAST-ACK 狀態(tài)??蛻舳耸盏结尫耪埱蠛螅蚍?wù)端發(fā)送確認應(yīng)答,此時客戶端進入 TIME-WAIT 狀態(tài)。該狀態(tài)會持續(xù) 2MSL(最大段生存期,指報文段在網(wǎng)絡(luò)中生存的時間,超時會被拋棄) 時間,若該時間段內(nèi)沒有服務(wù)端的重發(fā)請求的話,就進入 CLOSED 狀態(tài)。當(dāng)服務(wù)端收到確認應(yīng)答后,也便進入 CLOSED 狀態(tài)。

12. 對keep-alive的理解

HTTP1.0 中默認是在每次請求/應(yīng)答,客戶端和服務(wù)器都要新建一個連接,完成之后立即斷開連接,這就是短連接。當(dāng)使用Keep-Alive模式時,Keep-Alive功能使客戶端到服務(wù)器端的連接持續(xù)有效,當(dāng)出現(xiàn)對服務(wù)器的后繼請求時,Keep-Alive功能避免了建立或者重新建立連接,這就是長連接。其使用方法如下:

  • HTTP1.0版本是默認沒有Keep-alive的(也就是默認會發(fā)送keep-alive),所以要想連接得到保持,必須手動配置發(fā)送 ?Connection: keep-alive?字段。若想斷開keep-alive連接,需發(fā)送 ?Connection:close?字段;
  • HTTP1.1規(guī)定了默認保持長連接,數(shù)據(jù)傳輸完成了保持TCP連接不斷開,等待在同域名下繼續(xù)用這個通道傳輸數(shù)據(jù)。如果需要關(guān)閉,需要客戶端發(fā)送 ?Connection:close?首部字段。

Keep-Alive的建立過程

  • 客戶端向服務(wù)器在發(fā)送請求報文同時在首部添加發(fā)送Connection字段
  • 服務(wù)器收到請求并處理 Connection字段
  • 服務(wù)器回送Connection:Keep-Alive字段給客戶端
  • 客戶端接收到Connection字段
  • Keep-Alive連接建立成功

服務(wù)端自動斷開過程(也就是沒有keep-alive)

  • 客戶端向服務(wù)器只是發(fā)送內(nèi)容報文(不包含Connection字段)
  • 服務(wù)器收到請求并處理
  • 服務(wù)器返回客戶端請求的資源并關(guān)閉連接
  • 客戶端接收資源,發(fā)現(xiàn)沒有Connection字段,斷開連接

客戶端請求斷開連接過程

  • 客戶端向服務(wù)器發(fā)送Connection:close字段
  • 服務(wù)器收到請求并處理connection字段
  • 服務(wù)器回送響應(yīng)資源并斷開連接
  • 客戶端接收資源并斷開連接

開啟Keep-Alive的優(yōu)點:

  • 較少的CPU和內(nèi)存的使?(由于同時打開的連接的減少了);
  • 允許請求和應(yīng)答的HTTP管線化;
  • 降低擁塞控制 (TCP連接減少了);
  • 減少了后續(xù)請求的延遲(?需再進?握?);
  • 報告錯誤?需關(guān)閉TCP連;

開啟Keep-Alive的缺點

  • 長時間的Tcp連接容易導(dǎo)致系統(tǒng)資源無效占用,浪費系統(tǒng)資源。

13. 頁面有多張圖片,HTTP是怎樣的加載表現(xiàn)?

  • 在 HTTP 1下,瀏覽器對一個域名下最大TCP連接數(shù)為6,所以會請求多次??梢杂?b>多域名部署解決。這樣可以提高同時請求的數(shù)目,加快頁面圖片的獲取速度。
  • 在 HTTP 2下,可以一瞬間加載出來很多資源,因為,HTTP2支持多路復(fù)用,可以在一個TCP連接中發(fā)送多個HTTP請求。

14. HTTP2的頭部壓縮算法是怎樣的?

HTTP2的頭部壓縮是HPACK算法。在客戶端和服務(wù)器兩端建立“字典”,用索引號表示重復(fù)的字符串,采用哈夫曼編碼來壓縮整數(shù)和字符串,可以達到50%~90%的高壓縮率。

具體來說:

  • 在客戶端和服務(wù)器端使用“首部表”來跟蹤和存儲之前發(fā)送的鍵值對,對于相同的數(shù)據(jù),不再通過每次請求和響應(yīng)發(fā)送;
  • 首部表在HTTP/2的連接存續(xù)期內(nèi)始終存在,由客戶端和服務(wù)器共同漸進地更新;
  • 每個新的首部鍵值對要么被追加到當(dāng)前表的末尾,要么替換表中之前的值。

例如下圖中的兩個請求, 請求一發(fā)送了所有的頭部字段,第二個請求則只需要發(fā)送差異數(shù)據(jù),這樣可以減少冗余數(shù)據(jù),降低開銷。


15. HTTP請求報文的是什么樣的?

請求報?有4部分組成:

  • 請求?
  • 請求頭部
  • 空?
  • 請求體

image.png

其中:

(1)請求?包括:請求?法字段、URL字段、HTTP協(xié)議版本字段。它們?空格分隔。例如,GET /index.html HTTP/1.1。

(2)請求頭部:請求頭部由關(guān)鍵字/值對組成,每??對,關(guān)鍵字和值?英?冒號“:”分隔

  • User-Agent:產(chǎn)?請求的瀏覽器類型。
  • Accept:客戶端可識別的內(nèi)容類型列表。
  • Host:請求的主機名,允許多個域名同處?個IP地址,即虛擬主機。

(3)請求體: post put等請求攜帶的數(shù)據(jù)

image.png

16. HTTP響應(yīng)報文的是什么樣的?

請求報?有4部分組成:

  • 響應(yīng)?
  • 響應(yīng)頭
  • 空?
  • 響應(yīng)體

image.png

  • 響應(yīng)?:由網(wǎng)絡(luò)協(xié)議版本,狀態(tài)碼和狀態(tài)碼的原因短語組成,例如 HTTP/1.1 200 OK 。
  • 響應(yīng)頭:響應(yīng)部?組成
  • 響應(yīng)體:服務(wù)器響應(yīng)的數(shù)據(jù)

17. HTTP協(xié)議的優(yōu)點和缺點

HTTP 是超文本傳輸協(xié)議,它定義了客戶端和服務(wù)器之間交換報文的格式和方式,默認使用 80 端口。它使用 TCP 作為傳輸層協(xié)議,保證了數(shù)據(jù)傳輸?shù)目煽啃浴?

HTTP協(xié)議具有以下優(yōu)點

  • 支持客戶端/服務(wù)器模式
  • 簡單快速:客戶向服務(wù)器請求服務(wù)時,只需傳送請求方法和路徑。由于 HTTP 協(xié)議簡單,使得 HTTP 服務(wù)器的程序規(guī)模小,因而通信速度很快。
  • 無連接:無連接就是限制每次連接只處理一個請求。服務(wù)器處理完客戶的請求,并收到客戶的應(yīng)答后,即斷開連接,采用這種方式可以節(jié)省傳輸時間。
  • 無狀態(tài):HTTP 協(xié)議是無狀態(tài)協(xié)議,這里的狀態(tài)是指通信過程的上下文信息。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能會導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務(wù)器不需要先前信息時它的應(yīng)答就比較快。
  • 靈活:HTTP 允許傳輸任意類型的數(shù)據(jù)對象。正在傳輸?shù)念愋陀?nbsp;Content-Type 加以標(biāo)記。

HTTP協(xié)議具有以下缺點

  • 無狀態(tài):HTTP 是一個無狀態(tài)的協(xié)議,HTTP 服務(wù)器不會保存關(guān)于客戶的任何信息。
  • 明文傳輸:協(xié)議中的報文使用的是文本形式,這就直接暴露給外界,不安全。
  • 不安全

(1)通信使用明文(不加密),內(nèi)容可能會被竊聽;

(2)不驗證通信方的身份,因此有可能遭遇偽裝;

(3)無法證明報文的完整性,所以有可能已遭篡改;

18. 說一下HTTP 3.0

HTTP/3基于UDP協(xié)議實現(xiàn)了類似于TCP的多路復(fù)用數(shù)據(jù)流、傳輸可靠性等功能,這套功能被稱為QUIC協(xié)議。

image

  1. 流量控制、傳輸可靠性功能:QUIC在UDP的基礎(chǔ)上增加了一層來保證數(shù)據(jù)傳輸可靠性,它提供了數(shù)據(jù)包重傳、擁塞控制、以及其他一些TCP中的特性。
  2. 集成TLS加密功能:目前QUIC使用TLS1.3,減少了握手所花費的RTT數(shù)。
  3. 多路復(fù)用:同一物理連接上可以有多個獨立的邏輯數(shù)據(jù)流,實現(xiàn)了數(shù)據(jù)流的單獨傳輸,解決了TCP的隊頭阻塞問題。
  4. image

  5. 快速握手:由于基于UDP,可以實現(xiàn)使用0 ~ 1個RTT來建立連接。

19. HTTP協(xié)議的性能怎么樣

HTTP 協(xié)議是基于 TCP/IP,并且使用了請求-應(yīng)答的通信模式,所以性能的關(guān)鍵就在這兩點里。

  • 長連接

HTTP協(xié)議有兩種連接模式,一種是持續(xù)連接,一種非持續(xù)連接。

(1)非持續(xù)連接指的是服務(wù)器必須為每一個請求的對象建立和維護一個全新的連接。

(2)持續(xù)連接下,TCP 連接默認不關(guān)閉,可以被多個請求復(fù)用。采用持續(xù)連接的好處是可以避免每次建立 TCP 連接三次握手時所花費的時間。

對于不同版本的采用不同的連接方式:

  • 在HTTP/1.0 每發(fā)起一個請求,都要新建一次 TCP 連接(三次握手),而且是串行請求,做了無畏的 TCP 連接建立和斷開,增加了通信開銷。該版本使用的非持續(xù)的連接,但是可以在請求時,加上 Connection: keep-a live 來要求服務(wù)器不要關(guān)閉 TCP 連接。
  • 在HTTP/1.1 提出了長連接的通信方式,也叫持久連接。這種方式的好處在于減少了 TCP 連接的重復(fù)建立和斷開所造成的額外開銷,減輕了服務(wù)器端的負載。該版本及以后版本默認采用的是持續(xù)的連接。目前對于同一個域,大多數(shù)瀏覽器支持同時建立 6 個持久連接。

image

  • 管道網(wǎng)絡(luò)傳輸

HTTP/1.1 采用了長連接的方式,這使得管道(pipeline)網(wǎng)絡(luò)傳輸成為了可能。

管道(pipeline)網(wǎng)絡(luò)傳輸是指:可以在同一個 TCP 連接里面,客戶端可以發(fā)起多個請求,只要第一個請求發(fā)出去了,不必等其回來,就可以發(fā)第二個請求出去,可以減少整體的響應(yīng)時間。但是服務(wù)器還是按照順序回應(yīng)請求。如果前面的回應(yīng)特別慢,后面就會有許多請求排隊等著。這稱為隊頭堵塞。

  • 隊頭堵塞

HTTP 傳輸?shù)膱笪谋仨毷且话l(fā)一收,但是,里面的任務(wù)被放在一個任務(wù)隊列中串行執(zhí)行,一旦隊首的請求處理太慢,就會阻塞后面請求的處理。這就是HTTP隊頭阻塞問題。

隊頭阻塞的解決方案:

(1)并發(fā)連接:對于一個域名允許分配多個長連接,那么相當(dāng)于增加了任務(wù)隊列,不至于一個隊伍的任務(wù)阻塞其它所有任務(wù)。

(2)域名分片:將域名分出很多二級域名,它們都指向同樣的一臺服務(wù)器,能夠并發(fā)的長連接數(shù)變多,解決了隊頭阻塞的問題。

20. URL有哪些組成部分

以下面的URL為例:http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name

從上面的URL可以看出,一個完整的URL包括以下幾部分:

  • 協(xié)議部分:該URL的協(xié)議部分為“http:”,這代表網(wǎng)頁使用的是HTTP協(xié)議。在Internet中可以使用多種協(xié)議,如HTTP,F(xiàn)TP等等本例中使用的是HTTP協(xié)議。在"HTTP"后面的“//”為分隔符;
  • 域名部分:該URL的域名部分為“www.aspxfans.com”。一個URL中,也可以使用IP地址作為域名使用
  • 端口部分:跟在域名后面的是端口,域名和端口之間使用“:”作為分隔符。端口不是一個URL必須的部分,如果省略端口部分,將采用默認端口(HTTP協(xié)議默認端口是80,HTTPS協(xié)議默認端口是443);
  • 虛擬目錄部分:從域名后的第一個“/”開始到最后一個“/”為止,是虛擬目錄部分。虛擬目錄也不是一個URL必須的部分。本例中的虛擬目錄是“/news/”;
  • 文件名部分:從域名后的最后一個“/”開始到“?”為止,是文件名部分,如果沒有“?”,則是從域名后的最后一個“/”開始到“#”為止,是文件部分,如果沒有“?”和“#”,那么從域名后的最后一個“/”開始到結(jié)束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一個URL必須的部分,如果省略該部分,則使用默認的文件名;
  • 錨部分:從“#”開始到最后,都是錨部分。本例中的錨部分是“name”。錨部分也不是一個URL必須的部分;
  • 參數(shù)部分:從“?”開始到“#”為止之間的部分為參數(shù)部分,又稱搜索部分、查詢部分。本例中的參數(shù)部分為“boardID=5&ID=24618&page=1”。參數(shù)可以允許有多個參數(shù),參數(shù)與參數(shù)之間用“&”作為分隔符。

21. 與緩存相關(guān)的HTTP請求頭有哪些

強緩存:

  • Expires
  • Cache-Control

協(xié)商緩存:

  • Etag、If-None-Match
  • Last-Modified、If-Modified-Since

二、HTTPS協(xié)議


1. 什么是HTTPS協(xié)議?

超文本傳輸安全協(xié)議(Hypertext Transfer Protocol Secure,簡稱:HTTPS)是一種通過計算機網(wǎng)絡(luò)進行安全通信的傳輸協(xié)議。HTTPS經(jīng)由HTTP進行通信,利用SSL/TLS來加密數(shù)據(jù)包。HTTPS的主要目的是提供對網(wǎng)站服務(wù)器的身份認證,保護交換數(shù)據(jù)的隱私與完整性。

image

HTTP協(xié)議采用明文傳輸信息,存在信息竊聽、信息篡改信息劫持的風(fēng)險,而協(xié)議TLS/SSL具有身份驗證信息加密完整性校驗的功能,可以避免此類問題發(fā)生。

安全層的主要職責(zé)就是對發(fā)起的HTTP請求的數(shù)據(jù)進行加密操作 和 對接收到的HTTP的內(nèi)容進行解密操作。

2. TLS/SSL的工作原理

TLS/SSL全稱安全傳輸層協(xié)議(Transport Layer Security), 是介于TCP和HTTP之間的一層安全協(xié)議,不影響原有的TCP協(xié)議和HTTP協(xié)議,所以使用HTTPS基本上不需要對HTTP頁面進行太多的改造。

TLS/SSL的功能實現(xiàn)主要依賴三類基本算法:散列函數(shù)hash對稱加密、非對稱加密。這三類算法的作用如下:

  • 基于散列函數(shù)驗證信息的完整性
  • 對稱加密算法采用協(xié)商的秘鑰對數(shù)據(jù)加密
  • 非對稱加密實現(xiàn)身份認證和秘鑰協(xié)商

image

(1)散列函數(shù)hash

常見的散列函數(shù)有MD5、SHA1、SHA256。該函數(shù)的特點是單向不可逆,對輸入數(shù)據(jù)非常敏感,輸出的長度固定,任何數(shù)據(jù)的修改都會改變散列函數(shù)的結(jié)果,可以用于防止信息篡改并驗證數(shù)據(jù)的完整性。

特點:在信息傳輸過程中,散列函數(shù)不能三都實現(xiàn)信息防篡改,由于傳輸是明文傳輸,中間人可以修改信息后重新計算信息的摘要,所以需要對傳輸?shù)男畔⒑托畔⒄M行加密。

(2)對稱加密

對稱加密的方法是,雙方使用同一個秘鑰對數(shù)據(jù)進行加密和解密。但是對稱加密的存在一個問題,就是如何保證秘鑰傳輸?shù)陌踩?,因為秘鑰還是會通過網(wǎng)絡(luò)傳輸?shù)?,一旦秘鑰被其他人獲取到,那么整個加密過程就毫無作用了。 這就要用到非對稱加密的方法。

常見的對稱加密算法有AES-CBC、DES、3DES、AES-GCM等。相同的秘鑰可以用于信息的加密和解密。掌握秘鑰才能獲取信息,防止信息竊聽,其通訊方式是一對一。

特點:對稱加密的優(yōu)勢就是信息傳輸使用一對一,需要共享相同的密碼,密碼的安全是保證信息安全的基礎(chǔ),服務(wù)器和N個客戶端通信,需要維持N個密碼記錄且不能修改密碼。

(3)非對稱加密

非對稱加密的方法是,我們擁有兩個秘鑰,一個是公鑰,一個是私鑰。公鑰是公開的,私鑰是保密的。用私鑰加密的數(shù)據(jù),只有對應(yīng)的公鑰才能解密,用公鑰加密的數(shù)據(jù),只有對應(yīng)的私鑰才能解密。我們可以將公鑰公布出去,任何想和我們通信的客戶, 都可以使用我們提供的公鑰對數(shù)據(jù)進行加密,這樣我們就可以使用私鑰進行解密,這樣就能保證數(shù)據(jù)的安全了。但是非對稱加密有一個缺點就是加密的過程很慢,因此如果每次通信都使用非對稱加密的方式的話,反而會造成等待時間過長的問題。

常見的非對稱加密算法有RSA、ECC、DH等。秘鑰成對出現(xiàn),一般稱為公鑰(公開)和私鑰(保密)。公鑰加密的信息只有私鑰可以解開,私鑰加密的信息只能公鑰解開,因此掌握公鑰的不同客戶端之間不能相互解密信息,只能和服務(wù)器進行加密通信,服務(wù)器可以實現(xiàn)一對多的的通信,客戶端也可以用來驗證掌握私鑰的服務(wù)器的身份。

特點:非對稱加密的特點就是信息一對多,服務(wù)器只需要維持一個私鑰就可以和多個客戶端進行通信,但服務(wù)器發(fā)出的信息能夠被所有的客戶端解密,且該算法的計算復(fù)雜,加密的速度慢。

綜合上述算法特點,TLS/SSL的工作方式就是客戶端使用非對稱加密與服務(wù)器進行通信,實現(xiàn)身份的驗證并協(xié)商對稱加密使用的秘鑰。對稱加密算法采用協(xié)商秘鑰對信息以及信息摘要進行加密通信,不同節(jié)點之間采用的對稱秘鑰不同,從而保證信息只能通信雙方獲取。這樣就解決了兩個方法各自存在的問題。

3. 數(shù)字證書是什么?

現(xiàn)在的方法也不一定是安全的,因為沒有辦法確定得到的公鑰就一定是安全的公鑰??赡艽嬖谝粋€中間人,截取了對方發(fā)給我們的公鑰,然后將他自己的公鑰發(fā)送給我們,當(dāng)我們使用他的公鑰加密后發(fā)送的信息,就可以被他用自己的私鑰解密。然后他偽裝成我們以同樣的方法向?qū)Ψ桨l(fā)送信息,這樣我們的信息就被竊取了,然而自己還不知道。為了解決這樣的問題,可以使用數(shù)字證書。

首先使用一種 Hash 算法來對公鑰和其他信息進行加密,生成一個信息摘要,然后讓有公信力的認證中心(簡稱 CA )用它的私鑰對消息摘要加密,形成簽名。最后將原始的信息和簽名合在一起,稱為數(shù)字證書。當(dāng)接收方收到數(shù)字證書的時候,先根據(jù)原始信息使用同樣的 Hash 算法生成一個摘要,然后使用公證處的公鑰來對數(shù)字證書中的摘要進行解密,最后將解密的摘要和生成的摘要進行對比,就能發(fā)現(xiàn)得到的信息是否被更改了。

這個方法最要的是認證中心的可靠性,一般瀏覽器里會內(nèi)置一些頂層的認證中心的證書,相當(dāng)于我們自動信任了他們,只有這樣才能保證數(shù)據(jù)的安全。

image

4. HTTPS通信(握手)過程

HTTPS的通信過程如下:

  1. 客戶端向服務(wù)器發(fā)起請求,請求中包含使用的協(xié)議版本號、生成的一個隨機數(shù)、以及客戶端支持的加密方法。
  2. 服務(wù)器端接收到請求后,確認雙方使用的加密方法、并給出服務(wù)器的證書、以及一個服務(wù)器生成的隨機數(shù)。
  3. 客戶端確認服務(wù)器證書有效后,生成一個新的隨機數(shù),并使用數(shù)字證書中的公鑰,加密這個隨機數(shù),然后發(fā)給服 務(wù)器。并且還會提供一個前面所有內(nèi)容的 hash 的值,用來供服務(wù)器檢驗。
  4. 服務(wù)器使用自己的私鑰,來解密客戶端發(fā)送過來的隨機數(shù)。并提供前面所有內(nèi)容的 hash 值來供客戶端檢驗。
  5. 客戶端和服務(wù)器端根據(jù)約定的加密方法使用前面的三個隨機數(shù),生成對話秘鑰,以后的對話過程都使用這個秘鑰來加密信息。

5. HTTPS的特點

HTTPS的優(yōu)點如下:

  • 使用HTTPS協(xié)議可以認證用戶和服務(wù)器,確保數(shù)據(jù)發(fā)送到正確的客戶端和服務(wù)器;
  • 使用HTTPS協(xié)議可以進行加密傳輸、身份認證,通信更加安全,防止數(shù)據(jù)在傳輸過程中被竊取、修改,確保數(shù)據(jù)安全性;
  • HTTPS是現(xiàn)行架構(gòu)下最安全的解決方案,雖然不是絕對的安全,但是大幅增加了中間人攻擊的成本;

HTTPS的缺點如下:

  • HTTPS需要做服務(wù)器和客戶端雙方的加密個解密處理,耗費更多服務(wù)器資源,過程復(fù)雜;
  • HTTPS協(xié)議握手階段比較費時,增加頁面的加載時間;
  • SSL證書是收費的,功能越強大的證書費用越高;
  • HTTPS連接服務(wù)器端資源占用高很多,支持訪客稍多的網(wǎng)站需要投入更大的成本;
  • SSL證書需要綁定IP,不能再同一個IP上綁定多個域名。

6. HTTPS是如何保證安全的?

先理解兩個概念:

  • 對稱加密:即通信的雙?都使?同?個秘鑰進?加解密,對稱加密雖然很簡單性能也好,但是?法解決?次把秘鑰發(fā)給對?的問題,很容易被?客攔截秘鑰。
  • ?對稱加密:

\1. 私鑰 + 公鑰= 密鑰對

\2. 即?私鑰加密的數(shù)據(jù),只有對應(yīng)的公鑰才能解密,?公鑰加密的數(shù)據(jù),只有對應(yīng)的私鑰才能解密

\3. 因為通信雙?的??都有?套??的密鑰對,通信之前雙?會先把??的公鑰都先發(fā)給對?

\4. 然后對?再拿著這個公鑰來加密數(shù)據(jù)響應(yīng)給對?,等到到了對?那?,對?再???的私鑰進?解密

?對稱加密雖然安全性更?,但是帶來的問題就是速度很慢,影響性能。

解決?案:

結(jié)合兩種加密?式,將對稱加密的密鑰使??對稱加密的公鑰進?加密,然后發(fā)送出去,接收?使?私鑰進?解密得到對稱加密的密鑰,然后雙?可以使?對稱加密來進?溝通。

此時?帶來?個問題,中間?問題:

如果此時在客戶端和服務(wù)器之間存在?個中間?,這個中間?只需要把原本雙?通信互發(fā)的公鑰,換成??的公鑰,這樣中間?就可以輕松解密通信雙?所發(fā)送的所有數(shù)據(jù)。

所以這個時候需要?個安全的第三?頒發(fā)證書(CA),證明身份的身份,防?被中間?攻擊。 證書中包括:簽發(fā)者、證書?途、使?者公鑰、使?者私鑰、使?者的HASH算法、證書到期時間等。

但是問題來了,如果中間?篡改了證書,那么身份證明是不是就?效了?這個證明就?買了,這個時候需要?個新的技術(shù),數(shù)字簽名。

數(shù)字簽名就是?CA?帶的HASH算法對證書的內(nèi)容進?HASH得到?個摘要,再?CA的私鑰加密,最終組成數(shù)字簽名。當(dāng)別?把他的證書發(fā)過來的時候,我再?同樣的Hash算法,再次?成消息摘要,然后?CA的公鑰對數(shù)字簽名解密,得到CA創(chuàng)建的消息摘要,兩者??,就知道中間有沒有被?篡改了。這個時候就能最?程度保證通信的安全了。

三、HTTP狀態(tài)碼


狀態(tài)碼的類別:

類別 原因 描述
1xx Informational(信息性狀態(tài)碼) 接受的請求正在處理
2xx Success(成功狀態(tài)碼) 請求正常處理完畢
3xx Redirection(重定向狀態(tài)碼) 需要進行附加操作一完成請求
4xx Client Error (客戶端錯誤狀態(tài)碼) 服務(wù)器無法處理請求
5xx Server Error(服務(wù)器錯誤狀態(tài)碼) 服務(wù)器處理請求出錯

1. 2XX (Success 成功狀態(tài)碼)

狀態(tài)碼2XX表示請求被正常處理了。

(1)200 OK

200 OK表示客戶端發(fā)來的請求被服務(wù)器端正常處理了。

(2)204 No Content

該狀態(tài)碼表示客戶端發(fā)送的請求已經(jīng)在服務(wù)器端正常處理了,但是沒有返回的內(nèi)容,響應(yīng)報文中不包含實體的主體部分。一般在只需要從客戶端往服務(wù)器端發(fā)送信息,而服務(wù)器端不需要往客戶端發(fā)送內(nèi)容時使用。

(3)206 Partial Content

該狀態(tài)碼表示客戶端進行了范圍請求,而服務(wù)器端執(zhí)行了這部分的 GET 請求。響應(yīng)報文中包含由 Content-Range 指定范圍的實體內(nèi)容。

2. 3XX (Redirection 重定向狀態(tài)碼)

3XX 響應(yīng)結(jié)果表明瀏覽器需要執(zhí)行某些特殊的處理以正確處理請求。

(1)301 Moved Permanently

永久重定向。

該狀態(tài)碼表示請求的資源已經(jīng)被分配了新的 URI,以后應(yīng)使用資源指定的 URI。新的 URI 會在 HTTP 響應(yīng)頭中的 Location 首部字段指定。若用戶已經(jīng)把原來的URI保存為書簽,此時會按照 Location 中新的URI重新保存該書簽。同時,搜索引擎在抓取新內(nèi)容的同時也將舊的網(wǎng)址替換為重定向之后的網(wǎng)址。

使用場景:

  • 當(dāng)我們想換個域名,舊的域名不再使用時,用戶訪問舊域名時用301就重定向到新的域名。其實也是告訴搜索引擎收錄的域名需要對新的域名進行收錄。
  • 在搜索引擎的搜索結(jié)果中出現(xiàn)了不帶www的域名,而帶www的域名卻沒有收錄,這個時候可以用301重定向來告訴搜索引擎我們目標(biāo)的域名是哪一個。

(2)302 Found

臨時重定向。

該狀態(tài)碼表示請求的資源被分配到了新的 URI,希望用戶(本次)能使用新的 URI 訪問資源。和 301 Moved Permanently 狀態(tài)碼相似,但是 302 代表的資源不是被永久重定向,只是臨時性質(zhì)的。也就是說已移動的資源對應(yīng)的 URI 將來還有可能發(fā)生改變。若用戶把 URI 保存成書簽,但不會像 301 狀態(tài)碼出現(xiàn)時那樣去更新書簽,而是仍舊保留返回 302 狀態(tài)碼的頁面對應(yīng)的 URI。同時,搜索引擎會抓取新的內(nèi)容而保留舊的網(wǎng)址。因為服務(wù)器返回302代碼,搜索引擎認為新的網(wǎng)址只是暫時的。

使用場景:

  • 當(dāng)我們在做活動時,登錄到首頁自動重定向,進入活動頁面。
  • 未登陸的用戶訪問用戶中心重定向到登錄頁面。
  • 訪問404頁面重新定向到首頁。

(3)303 See Other

該狀態(tài)碼表示由于請求對應(yīng)的資源存在著另一個 URI,應(yīng)使用 GET 方法定向獲取請求的資源。

303 狀態(tài)碼和 302 Found 狀態(tài)碼有著相似的功能,但是 303 狀態(tài)碼明確表示客戶端應(yīng)當(dāng)采用 GET 方法獲取資源。

303 狀態(tài)碼通常作為 PUT 或 POST 操作的返回結(jié)果,它表示重定向鏈接指向的不是新上傳的資源,而是另外一個頁面,比如消息確認頁面或上傳進度頁面。而請求重定向頁面的方法要總是使用 GET。

注意:

  • 當(dāng) 301、302、303 響應(yīng)狀態(tài)碼返回時,幾乎所有的瀏覽器都會把 POST 改成GET,并刪除請求報文內(nèi)的主體,之后請求會再次自動發(fā)送。
  • 301、302 標(biāo)準(zhǔn)是禁止將 POST 方法變成 GET方法的,但實際大家都會這么做。

(4)304 Not Modified

瀏覽器緩存相關(guān)。

該狀態(tài)碼表示客戶端發(fā)送附帶條件的請求時,服務(wù)器端允許請求訪問資源,但未滿足條件的情況。304 狀態(tài)碼返回時,不包含任何響應(yīng)的主體部分。304 雖然被劃分在 3XX 類別中,但是和重定向沒有關(guān)系。

帶條件的請求(Http 條件請求):使用 Get方法 請求,請求報文中包含(if-matchif-none-match、if-modified-sinceif-unmodified-since、if-range)中任意首部。

狀態(tài)碼304并不是一種錯誤,而是告訴客戶端有緩存,直接使用緩存中的數(shù)據(jù)。返回頁面的只有頭部信息,是沒有內(nèi)容部分的,這樣在一定程度上提高了網(wǎng)頁的性能。

(5)307 Temporary Redirect

307表示臨時重定向。該狀態(tài)碼與 302 Found 有著相同含義,盡管 302 標(biāo)準(zhǔn)禁止 POST 變成 GET,但是實際使用時還是這樣做了。

307 會遵守瀏覽器標(biāo)準(zhǔn),不會從 POST 變成 GET。但是對于處理請求的行為時,不同瀏覽器還是會出現(xiàn)不同的情況。規(guī)范要求瀏覽器繼續(xù)向 Location 的地址 POST 內(nèi)容。規(guī)范要求瀏覽器繼續(xù)向 Location 的地址 POST 內(nèi)容。

3. 4XX (Client Error 客戶端錯誤狀態(tài)碼)

4XX 的響應(yīng)結(jié)果表明客戶端是發(fā)生錯誤的原因所在。

(1)400 Bad Request

該狀態(tài)碼表示請求報文中存在語法錯誤。當(dāng)錯誤發(fā)生時,需修改請求的內(nèi)容后再次發(fā)送請求。另外,瀏覽器會像 200 OK 一樣對待該狀態(tài)碼。

(2)401 Unauthorized

該狀態(tài)碼表示發(fā)送的請求需要有通過 HTTP 認證(BASIC 認證、DIGEST 認證)的認證信息。若之前已進行過一次請求,則表示用戶認證失敗

返回含有 401 的響應(yīng)必須包含一個適用于被請求資源的 WWW-Authenticate 首部用以質(zhì)詢(challenge)用戶信息。當(dāng)瀏覽器初次接收到 401 響應(yīng),會彈出認證用的對話窗口。

以下情況會出現(xiàn)401:

  • 401.1 - 登錄失敗。
  • 401.2 - 服務(wù)器配置導(dǎo)致登錄失敗。
  • 401.3 - 由于 ACL 對資源的限制而未獲得授權(quán)。
  • 401.4 - 篩選器授權(quán)失敗。
  • 401.5 - ISAPI/CGI 應(yīng)用程序授權(quán)失敗。
  • 401.7 - 訪問被 Web 服務(wù)器上的 URL 授權(quán)策略拒絕。這個錯誤代碼為 IIS 6.0 所專用。

(3)403 Forbidden

該狀態(tài)碼表明請求資源的訪問被服務(wù)器拒絕了,服務(wù)器端沒有必要給出詳細理由,但是可以在響應(yīng)報文實體的主體中進行說明。進入該狀態(tài)后,不能再繼續(xù)進行驗證。該訪問是永久禁止的,并且與應(yīng)用邏輯密切相關(guān)。

IIS 定義了許多不同的 403 錯誤,它們指明更為具體的錯誤原因:

  • 403.1 - 執(zhí)行訪問被禁止。
  • 403.2 - 讀訪問被禁止。
  • 403.3 - 寫訪問被禁止。
  • 403.4 - 要求 SSL。
  • 403.5 - 要求 SSL 128。
  • 403.6 - IP 地址被拒絕。
  • 403.7 - 要求客戶端證書。
  • 403.8 - 站點訪問被拒絕。
  • 403.9 - 用戶數(shù)過多。
  • 403.10 - 配置無效。
  • 403.11 - 密碼更改。
  • 403.12 - 拒絕訪問映射表。
  • 403.13 - 客戶端證書被吊銷。
  • 403.14 - 拒絕目錄列表。
  • 403.15 - 超出客戶端訪問許可。
  • 403.16 - 客戶端證書不受信任或無效。
  • 403.17 - 客戶端證書已過期或尚未生效
  • 403.18 - 在當(dāng)前的應(yīng)用程序池中不能執(zhí)行所請求的 URL。這個錯誤代碼為 IIS 6.0 所專用。
  • 403.19 - 不能為這個應(yīng)用程序池中的客戶端執(zhí)行 CGI。這個錯誤代碼為 IIS 6.0 所專用。
  • 403.20 - Passport 登錄失敗。這個錯誤代碼為 IIS 6.0 所專用。

(4)404 Not Found

該狀態(tài)碼表明服務(wù)器上無法找到請求的資源。除此之外,也可以在服務(wù)器端拒絕請求且不想說明理由時使用。

以下情況會出現(xiàn)404:

  • 404.0 -(無) – 沒有找到文件或目錄。
  • 404.1 - 無法在所請求的端口上訪問 Web 站點。
  • 404.2 - Web 服務(wù)擴展鎖定策略阻止本請求。
  • 404.3 - MIME 映射策略阻止本請求。

(5)405 Method Not Allowed

該狀態(tài)碼表示客戶端請求的方法雖然能被服務(wù)器識別,但是服務(wù)器禁止使用該方法。GET 和 HEAD 方法,服務(wù)器應(yīng)該總是允許客戶端進行訪問??蛻舳丝梢酝ㄟ^ OPTIONS 方法(預(yù)檢)來查看服務(wù)器允許的訪問方法, 如下

Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE

4. 5XX (Server Error 服務(wù)器錯誤狀態(tài)碼)

5XX 的響應(yīng)結(jié)果表明服務(wù)器本身發(fā)生錯誤.

(1)500 Internal Server Error

該狀態(tài)碼表明服務(wù)器端在執(zhí)行請求時發(fā)生了錯誤。也有可能是 Web 應(yīng)用存在的 bug 或某些臨時的故障。

(2)502 Bad Gateway

該狀態(tài)碼表明扮演網(wǎng)關(guān)或代理角色的服務(wù)器,從上游服務(wù)器中接收到的響應(yīng)是無效的。注意,502 錯誤通常不是客戶端能夠修復(fù)的,而是需要由途經(jīng)的 Web 服務(wù)器或者代理服務(wù)器對其進行修復(fù)。以下情況會出現(xiàn)502:

  • 502.1 - CGI (通用網(wǎng)關(guān)接口)應(yīng)用程序超時。
  • 502.2 - CGI (通用網(wǎng)關(guān)接口)應(yīng)用程序出錯。

(3)503 Service Unavailable

該狀態(tài)碼表明服務(wù)器暫時處于超負載或正在進行停機維護,現(xiàn)在無法處理請求。如果事先得知解除以上狀況需要的時間,最好寫入 RetryAfter 首部字段再返回給客戶端。

使用場景:

  • 服務(wù)器停機維護時,主動用503響應(yīng)請求;
  • nginx 設(shè)置限速,超過限速,會返回503。

(4)504 Gateway Timeout

該狀態(tài)碼表示網(wǎng)關(guān)或者代理的服務(wù)器無法在規(guī)定的時間內(nèi)獲得想要的響應(yīng)。他是HTTP 1.1中新加入的。

使用場景:代碼執(zhí)行時間超時,或者發(fā)生了死循環(huán)。

5. 總結(jié)

(1)2XX 成功

  • 200 OK,表示從客戶端發(fā)來的請求在服務(wù)器端被正確處理
  • 204 No content,表示請求成功,但響應(yīng)報文不含實體的主體部分
  • 205 Reset Content,表示請求成功,但響應(yīng)報文不含實體的主體部分,但是與 204 響應(yīng)不同在于要求請求方重置內(nèi)容
  • 206 Partial Content,進行范圍請求

(2)3XX 重定向

  • 301 moved permanently,永久性重定向,表示資源已被分配了新的 URL
  • 302 found,臨時性重定向,表示資源臨時被分配了新的 URL
  • 303 see other,表示資源存在著另一個 URL,應(yīng)使用 GET 方法獲取資源
  • 304 not modified,表示服務(wù)器允許訪問資源,但因發(fā)生請求未滿足條件的情況
  • 307 temporary redirect,臨時重定向,和302含義類似,但是期望客戶端保持請求方法不變向新的地址發(fā)出請求

(3)4XX 客戶端錯誤

  • 400 bad request,請求報文存在語法錯誤
  • 401 unauthorized,表示發(fā)送的請求需要有通過 HTTP 認證的認證信息
  • 403 forbidden,表示對請求資源的訪問被服務(wù)器拒絕
  • 404 not found,表示在服務(wù)器上沒有找到請求的資源

(4)5XX 服務(wù)器錯誤

  • 500 internal sever error,表示服務(wù)器端在執(zhí)行請求時發(fā)生了錯誤
  • 501 Not Implemented,表示服務(wù)器不支持當(dāng)前請求所需要的某個功能
  • 503 service unavailable,表明服務(wù)器暫時處于超負載或正在停機維護,無法處理請求

6. 同樣是重定向,307,303,302的區(qū)別?

302是http1.0的協(xié)議狀態(tài)碼,在http1.1版本的時候為了細化302狀態(tài)碼?出來了兩個303和307。 303明確表示客戶端應(yīng)當(dāng)采?get?法獲取資源,他會把POST請求變?yōu)镚ET請求進?重定向。 307會遵照瀏覽器標(biāo)準(zhǔn),不會從post變?yōu)間et。

四、DNS協(xié)議介紹


1. DNS 協(xié)議是什么

概念: DNS 是域名系統(tǒng) (Domain Name System) 的縮寫,提供的是一種主機名到 IP 地址的轉(zhuǎn)換服務(wù),就是我們常說的域名系統(tǒng)。它是一個由分層的 DNS 服務(wù)器組成的分布式數(shù)據(jù)庫,是定義了主機如何查詢這個分布式數(shù)據(jù)庫的方式的應(yīng)用層協(xié)議。能夠使人更方便的訪問互聯(lián)網(wǎng),而不用去記住能夠被機器直接讀取的IP數(shù)串。

作用: 將域名解析為IP地址,客戶端向DNS服務(wù)器(DNS服務(wù)器有自己的IP地址)發(fā)送域名查詢請求,DNS服務(wù)器告知客戶機Web服務(wù)器的 IP 地址。

2. DNS同時使用TCP和UDP協(xié)議?

DNS占用53號端口,同時使用TCP和UDP協(xié)議。

(1)在區(qū)域傳輸?shù)臅r候使用TCP協(xié)議

  • 輔域名服務(wù)器會定時(一般3小時)向主域名服務(wù)器進行查詢以便了解數(shù)據(jù)是否有變動。如有變動,會執(zhí)行一次區(qū)域傳送,進行數(shù)據(jù)同步。區(qū)域傳送使用TCP而不是UDP,因為數(shù)據(jù)同步傳送的數(shù)據(jù)量比一個請求應(yīng)答的數(shù)據(jù)量要多得多。
  • TCP是一種可靠連接,保證了數(shù)據(jù)的準(zhǔn)確性。

(2)在域名解析的時候使用UDP協(xié)議

  • 客戶端向DNS服務(wù)器查詢域名,一般返回的內(nèi)容都不超過512字節(jié),用UDP傳輸即可。不用經(jīng)過三次握手,這樣DNS服務(wù)器負載更低,響應(yīng)更快。理論上說,客戶端也可以指定向DNS服務(wù)器查詢時用TCP,但事實上,很多DNS服務(wù)器進行配置的時候,僅支持UDP查詢包。

3. DNS完整的查詢過程

DNS服務(wù)器解析域名的過程:

  • 首先會在瀏覽器的緩存中查找對應(yīng)的IP地址,如果查找到直接返回,若找不到繼續(xù)下一步
  • 將請求發(fā)送給本地DNS服務(wù)器,在本地域名服務(wù)器緩存中查詢,如果查找到,就直接將查找結(jié)果返回,若找不到繼續(xù)下一步
  • 本地DNS服務(wù)器向根域名服務(wù)器發(fā)送請求,根域名服務(wù)器會返回一個所查詢域的頂級域名服務(wù)器地址
  • 本地DNS服務(wù)器向頂級域名服務(wù)器發(fā)送請求,接受請求的服務(wù)器查詢自己的緩存,如果有記錄,就返回查詢結(jié)果,如果沒有就返回相關(guān)的下一級的權(quán)威域名服務(wù)器的地址
  • 本地DNS服務(wù)器向權(quán)威域名服務(wù)器發(fā)送請求,域名服務(wù)器返回對應(yīng)的結(jié)果
  • 本地DNS服務(wù)器將返回結(jié)果保存在緩存中,便于下次使用
  • 本地DNS服務(wù)器將返回結(jié)果返回給瀏覽器

比如要查詢 www.baidu.com 的 IP 地址,首先會在瀏覽器的緩存中查找是否有該域名的緩存,如果不存在就將請求發(fā)送到本地的 DNS 服務(wù)器中,本地DNS服務(wù)器會判斷是否存在該域名的緩存,如果不存在,則向根域名服務(wù)器發(fā)送一個請求,根域名服務(wù)器返回負責(zé) .com 的頂級域名服務(wù)器的 IP 地址的列表。然后本地 DNS 服務(wù)器再向其中一個負責(zé) .com 的頂級域名服務(wù)器發(fā)送一個請求,負責(zé) .com 的頂級域名服務(wù)器返回負責(zé) .baidu 的權(quán)威域名服務(wù)器的 IP 地址列表。然后本地 DNS 服務(wù)器再向其中一個權(quán)威域名服務(wù)器發(fā)送一個請求,最后權(quán)威域名服務(wù)器返回一個對應(yīng)的主機名的 IP 地址列表。

4. 迭代查詢與遞歸查詢

實際上,DNS解析是一個包含迭代查詢和遞歸查詢的過程。

  • 遞歸查詢指的是查詢請求發(fā)出后,域名服務(wù)器代為向下一級域名服務(wù)器發(fā)出請求,最后向用戶返回查詢的最終結(jié)果。使用遞歸 查詢,用戶只需要發(fā)出一次查詢請求。
  • 迭代查詢指的是查詢請求后,域名服務(wù)器返回單次查詢的結(jié)果。下一級的查詢由用戶自己請求。使用迭代查詢,用戶需要發(fā)出 多次的查詢請求。

一般我們向本地 DNS 服務(wù)器發(fā)送請求的方式就是遞歸查詢,因為我們只需要發(fā)出一次請求,然后本地 DNS 服務(wù)器返回給我 們最終的請求結(jié)果。而本地 DNS 服務(wù)器向其他域名服務(wù)器請求的過程是迭代查詢的過程,因為每一次域名服務(wù)器只返回單次 查詢的結(jié)果,下一級的查詢由本地 DNS 服務(wù)器自己進行。

5. DNS 記錄和報文

DNS 服務(wù)器中以資源記錄的形式存儲信息,每一個 DNS 響應(yīng)報文一般包含多條資源記錄。一條資源記錄的具體的格式為

(Name,Value,Type,TTL)

其中 TTL 是資源記錄的生存時間,它定義了資源記錄能夠被其他的 DNS 服務(wù)器緩存多長時間。

常用的一共有四種 Type 的值,分別是 A、NS、CNAME 和 MX ,不同 Type 的值,對應(yīng)資源記錄代表的意義不同:

  • 如果 Type = A,則 Name 是主機名,Value 是主機名對應(yīng)的 IP 地址。因此一條記錄為 A 的資源記錄,提供了標(biāo) 準(zhǔn)的主機名到 IP 地址的映射。
  • 如果 Type = NS,則 Name 是個域名,Value 是負責(zé)該域名的 DNS 服務(wù)器的主機名。這個記錄主要用于 DNS 鏈?zhǔn)?查詢時,返回下一級需要查詢的 DNS 服務(wù)器的信息。
  • 如果 Type = CNAME,則 Name 為別名,Value 為該主機的規(guī)范主機名。該條記錄用于向查詢的主機返回一個主機名 對應(yīng)的規(guī)范主機名,從而告訴查詢主機去查詢這個主機名的 IP 地址。主機別名主要是為了通過給一些復(fù)雜的主機名提供 一個便于記憶的簡單的別名。
  • 如果 Type = MX,則 Name 為一個郵件服務(wù)器的別名,Value 為郵件服務(wù)器的規(guī)范主機名。它的作用和 CNAME 是一 樣的,都是為了解決規(guī)范主機名不利于記憶的缺點。

五、網(wǎng)絡(luò)模型


1. OSI七層模型

ISO為了更好的使網(wǎng)絡(luò)應(yīng)用更為普及,推出了 OSI參考模型。

image

(1)應(yīng)用層

OSI參考模型中最靠近用戶的一層,是為計算機用戶提供應(yīng)用接口,也為用戶直接提供各種網(wǎng)絡(luò)服務(wù)。我們常見應(yīng)用層的網(wǎng)絡(luò)服務(wù)協(xié)議有:HTTP,HTTPS,FTPPOP3、SMTP等。

  • 在客戶端與服務(wù)器中經(jīng)常會有數(shù)據(jù)的請求,這個時候就是會用到 ?http(hyper text transfer protocol)(超文本傳輸協(xié)議)?或者 ?https?在后端設(shè)計數(shù)據(jù)接口時,我們常常使用到這個協(xié)議。
  • ?FTP?是文件傳輸協(xié)議,在開發(fā)過程中,個人并沒有涉及到,但是我想,在一些資源網(wǎng)站,比如 百度網(wǎng)盤 迅雷應(yīng)該是基于此協(xié)議的。
  • ?SMTP?是 ?simple mail transfer protocol(簡單郵件傳輸協(xié)議)?。在一個項目中,在用戶郵箱驗證碼登錄的功能時,使用到了這個協(xié)議。

(2)表示層

表示層提供各種用于應(yīng)用層數(shù)據(jù)的編碼和轉(zhuǎn)換功能,確保一個系統(tǒng)的應(yīng)用層發(fā)送的數(shù)據(jù)能被另一個系統(tǒng)的應(yīng)用層識別。如果必要,該層可提供一種標(biāo)準(zhǔn)表示形式,用于將計算機內(nèi)部的多種數(shù)據(jù)格式轉(zhuǎn)換成通信中采用的標(biāo)準(zhǔn)表示形式。數(shù)據(jù)壓縮和加密也是表示層可提供的轉(zhuǎn)換功能之一。

在項目開發(fā)中,為了方便數(shù)據(jù)傳輸,可以使用 base64對數(shù)據(jù)進行編解碼。如果按功能來劃分,base64應(yīng)該是工作在表示層。

(3)會話層

會話層就是負責(zé)建立、管理和終止表示層實體之間的通信會話。該層的通信由不同設(shè)備中的應(yīng)用程序之間的服務(wù)請求和響應(yīng)組成。

(4)傳輸層

傳輸層建立了主機端到端的鏈接,傳輸層的作用是為上層協(xié)議提供端到端的可靠和透明的數(shù)據(jù)傳輸服務(wù),包括處理差錯控制和流量控制等問題。該層向高層屏蔽了下層數(shù)據(jù)通信的細節(jié),使高層用戶看到的只是在兩個傳輸實體間的一條主機到主機的、可由用戶控制和設(shè)定的、可靠的數(shù)據(jù)通路。我們通常說的,TCP UDP就是在這一層。端口號既是這里的“端”。

(5)網(wǎng)絡(luò)層

本層通過 IP尋址來建立兩個節(jié)點之間的連接,為源端的運輸層送來的分組,選擇合適的路由和交換節(jié)點,正確無誤地按照地址傳送給目的端的運輸層。就是通常說的 IP層。這一層就是我們經(jīng)常說的 IP協(xié)議層。IP協(xié)議是 Internet的基礎(chǔ)。我們可以這樣理解,網(wǎng)絡(luò)層規(guī)定了數(shù)據(jù)包的傳輸路線,而傳輸層則規(guī)定了數(shù)據(jù)包的傳輸方式。

(6)數(shù)據(jù)鏈路層

將比特組合成字節(jié),再將字節(jié)組合成幀,使用鏈路層地址 (以太網(wǎng)使用MAC地址)來訪問介質(zhì),并進行差錯檢測。

網(wǎng)絡(luò)層與數(shù)據(jù)鏈路層的對比,通過上面的描述,我們或許可以這樣理解,網(wǎng)絡(luò)層是規(guī)劃了數(shù)據(jù)包的傳輸路線,而數(shù)據(jù)鏈路層就是傳輸路線。不過,在數(shù)據(jù)鏈路層上還增加了差錯控制的功能。

(7)物理層

實際最終信號的傳輸是通過物理層實現(xiàn)的。通過物理介質(zhì)傳輸比特流。規(guī)定了電平、速度和電纜針腳。常用設(shè)備有(各種物理設(shè)備)集線器、中繼器、調(diào)制解調(diào)器、網(wǎng)線、雙絞線、同軸電纜。這些都是物理層的傳輸介質(zhì)。

OSI七層模型通信特點:對等通信

對等通信,為了使數(shù)據(jù)分組從源傳送到目的地,源端OSI模型的每一層都必須與目的端的對等層進行通信,這種通信方式稱為對等層通信。在每一層通信過程中,使用本層自己協(xié)議進行通信。

2. TCP/IP五層協(xié)議

TCP/IP五層協(xié)議和 OSI的七層協(xié)議對應(yīng)關(guān)系如下:

image

  • 應(yīng)用層 (application layer):直接為應(yīng)用進程提供服務(wù)。應(yīng)用層協(xié)議定義的是應(yīng)用進程間通訊和交互的規(guī)則,不同的應(yīng)用有著不同的應(yīng)用層協(xié)議,如 HTTP協(xié)議(萬維網(wǎng)服務(wù))、FTP協(xié)議(文件傳輸)、SMTP協(xié)議(電子郵件)、DNS(域名查詢)等。
  • 傳輸層 (transport layer):有時也譯為運輸層,它負責(zé)為兩臺主機中的進程提供通信服務(wù)。該層主要有以下兩種協(xié)議:
    • 傳輸控制協(xié)議 (Transmission Control Protocol,TCP):提供面向連接的、可靠的數(shù)據(jù)傳輸服務(wù),數(shù)據(jù)傳輸?shù)幕締挝皇菆笪亩危╯egment);
    • 用戶數(shù)據(jù)報協(xié)議 (User Datagram Protocol,UDP):提供無連接的、盡最大努力的數(shù)據(jù)傳輸服務(wù),但不保證數(shù)據(jù)傳輸?shù)目煽啃?,?shù)據(jù)傳輸?shù)幕締挝皇怯脩魯?shù)據(jù)報。
  • 網(wǎng)絡(luò)層 (internet layer):有時也譯為網(wǎng)際層,它負責(zé)為兩臺主機提供通信服務(wù),并通過選擇合適的路由將數(shù)據(jù)傳遞到目標(biāo)主機。
  • 數(shù)據(jù)鏈路層 (data link layer):負責(zé)將網(wǎng)絡(luò)層交下來的 IP 數(shù)據(jù)報封裝成幀,并在鏈路的兩個相鄰節(jié)點間傳送幀,每一幀都包含數(shù)據(jù)和必要的控制信息(如同步信息、地址信息、差錯控制等)。
  • 物理層 (physical Layer):確保數(shù)據(jù)可以在各種物理媒介上進行傳輸,為數(shù)據(jù)的傳輸提供可靠的環(huán)境。

從上圖中可以看出,TCP/IP模型比 OSI模型更加簡潔,它把 應(yīng)用層/表示層/會話層全部整合為了 應(yīng)用層。

在每一層都工作著不同的設(shè)備,比如我們常用的交換機就工作在數(shù)據(jù)鏈路層的,一般的路由器是工作在網(wǎng)絡(luò)層的。

image

在每一層實現(xiàn)的協(xié)議也各不同,即每一層的服務(wù)也不同,下圖列出了每層主要的傳輸協(xié)議:

image

同樣,TCP/IP五層協(xié)議的通信方式也是對等通信:

image.png

六、TCP與UDP


1. TCP 和 UDP的概念及特點

TCP 和 UDP都是傳輸層協(xié)議,他們都屬于TCP/IP協(xié)議族:

(1)UDP

UDP的全稱是用戶數(shù)據(jù)報協(xié)議,在網(wǎng)絡(luò)中它與TCP協(xié)議一樣用于處理數(shù)據(jù)包,是一種無連接的協(xié)議。在OSI模型中,在傳輸層,處于IP協(xié)議的上一層。UDP有不提供數(shù)據(jù)包分組、組裝和不能對數(shù)據(jù)包進行排序的缺點,也就是說,當(dāng)報文發(fā)送之后,是無法得知其是否安全完整到達的。

它的特點如下:

1)面向無連接

首先 UDP 是不需要和 TCP一樣在發(fā)送數(shù)據(jù)前進行三次握手建立連接的,想發(fā)數(shù)據(jù)就可以開始發(fā)送了。并且也只是數(shù)據(jù)報文的搬運工,不會對數(shù)據(jù)報文進行任何拆分和拼接操作。

具體來說就是:

  • 在發(fā)送端,應(yīng)用層將數(shù)據(jù)傳遞給傳輸層的 UDP 協(xié)議,UDP 只會給數(shù)據(jù)增加一個 UDP 頭標(biāo)識下是 UDP 協(xié)議,然后就傳遞給網(wǎng)絡(luò)層了
  • 在接收端,網(wǎng)絡(luò)層將數(shù)據(jù)傳遞給傳輸層,UDP 只去除 IP 報文頭就傳遞給應(yīng)用層,不會任何拼接操作

2)有單播,多播,廣播的功能

UDP 不止支持一對一的傳輸方式,同樣支持一對多,多對多,多對一的方式,也就是說 UDP 提供了單播,多播,廣播的功能。

3)面向報文

發(fā)送方的UDP對應(yīng)用程序交下來的報文,在添加首部后就向下交付IP層。UDP對應(yīng)用層交下來的報文,既不合并,也不拆分,而是保留這些報文的邊界。因此,應(yīng)用程序必須選擇合適大小的報文

4)不可靠性

首先不可靠性體現(xiàn)在無連接上,通信都不需要建立連接,想發(fā)就發(fā),這樣的情況肯定不可靠。

并且收到什么數(shù)據(jù)就傳遞什么數(shù)據(jù),并且也不會備份數(shù)據(jù),發(fā)送數(shù)據(jù)也不會關(guān)心對方是否已經(jīng)正確接收到數(shù)據(jù)了。

再者網(wǎng)絡(luò)環(huán)境時好時壞,但是 UDP 因為沒有擁塞控制,一直會以恒定的速度發(fā)送數(shù)據(jù)。即使網(wǎng)絡(luò)條件不好,也不會對發(fā)送速率進行調(diào)整。這樣實現(xiàn)的弊端就是在網(wǎng)絡(luò)條件不好的情況下可能會導(dǎo)致丟包,但是優(yōu)點也很明顯,在某些實時性要求高的場景(比如電話會議)就需要使用 UDP 而不是 TCP。

5)頭部開銷小,傳輸數(shù)據(jù)報文時是很高效的。

image

UDP 頭部包含了以下幾個數(shù)據(jù):

  • 兩個十六位的端口號,分別為源端口(可選字段)和目標(biāo)端口
  • 整個數(shù)據(jù)報文的長度
  • 整個數(shù)據(jù)報文的檢驗和(IPv4 可選字段),該字段用于發(fā)現(xiàn)頭部信息和數(shù)據(jù)中的錯誤

因此 UDP 的頭部開銷小,只有8字節(jié),相比 TCP 的至少20字節(jié)要少得多,在傳輸數(shù)據(jù)報文時是很高效的。

(2)TCP

TCP的全稱是傳輸控制協(xié)議是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。TCP 是面向連接的、可靠的流協(xié)議(流就是指不間斷的數(shù)據(jù)結(jié)構(gòu))。

它有以下幾個特點:

1)面向連接

面向連接,是指發(fā)送數(shù)據(jù)之前必須在兩端建立連接。建立連接的方法是“三次握手”,這樣能建立可靠的連接。建立連接,是為數(shù)據(jù)的可靠傳輸打下了基礎(chǔ)。

2)僅支持單播傳輸

每條TCP傳輸連接只能有兩個端點,只能進行點對點的數(shù)據(jù)傳輸,不支持多播和廣播傳輸方式。

3)面向字節(jié)流

TCP不像UDP一樣那樣一個個報文獨立地傳輸,而是在不保留報文邊界的情況下以字節(jié)流方式進行傳輸。

4)可靠傳輸

對于可靠傳輸,判斷丟包、誤碼靠的是TCP的段編號以及確認號。TCP為了保證報文傳輸?shù)目煽?,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然后接收端實體對已成功收到的字節(jié)發(fā)回一個相應(yīng)的確認(ACK);如果發(fā)送端實體在合理的往返時延(RTT)內(nèi)未收到確認,那么對應(yīng)的數(shù)據(jù)(假設(shè)丟失了)將會被重傳。

5)提供擁塞控制

當(dāng)網(wǎng)絡(luò)出現(xiàn)擁塞的時候,TCP能夠減小向網(wǎng)絡(luò)注入數(shù)據(jù)的速率和數(shù)量,緩解擁塞。

6)提供全雙工通信

TCP允許通信雙方的應(yīng)用程序在任何時候都能發(fā)送數(shù)據(jù),因為TCP連接的兩端都設(shè)有緩存,用來臨時存放雙向通信的數(shù)據(jù)。當(dāng)然,TCP可以立即發(fā)送一個數(shù)據(jù)段,也可以緩存一段時間以便一次發(fā)送更多的數(shù)據(jù)段(最大的數(shù)據(jù)段大小取決于MSS)

2. TCP和UDP的區(qū)別

UDP TCP
是否連接 無連接 面向連接
是否可靠 不可靠傳輸,不使用流量控制和擁塞控制 可靠傳輸(數(shù)據(jù)順序和正確性),使用流量控制和擁塞控制
連接對象個數(shù) 支持一對一,一對多,多對一和多對多交互通信 只能是一對一通信
傳輸方式 面向報文 面向字節(jié)流
首部開銷 首部開銷小,僅8字節(jié) 首部最小20字節(jié),最大60字節(jié)
適用場景 適用于實時應(yīng)用,例如視頻會議、直播 適用于要求可靠傳輸?shù)膽?yīng)用,例如文件傳輸

3. TCP和UDP的使用場景

  • TCP應(yīng)用場景: 效率要求相對低,但對準(zhǔn)確性要求相對高的場景。因為傳輸中需要對數(shù)據(jù)確認、重發(fā)、排序等操作,相比之下效率沒有UDP高。例如:文件傳輸(準(zhǔn)確高要求高、但是速度可以相對慢)、接受郵件、遠程登錄。
  • UDP應(yīng)用場景: 效率要求相對高,對準(zhǔn)確性要求相對低的場景。例如:QQ聊天、在線視頻、網(wǎng)絡(luò)語音電話(即時通訊,速度要求高,但是出現(xiàn)偶爾斷續(xù)不是太大問題,并且此處完全不可以使用重發(fā)機制)、廣播通信(廣播、多播)。

4. UDP協(xié)議為什么不可靠?

UDP在傳輸數(shù)據(jù)之前不需要先建立連接,遠地主機的運輸層在接收到UDP報文后,不需要確認,提供不可靠交付??偨Y(jié)就以下四點:

  • 不保證消息交付:不確認,不重傳,無超時
  • 不保證交付順序:不設(shè)置包序號,不重排,不會發(fā)生隊首阻塞
  • 不跟蹤連接狀態(tài):不必建立連接或重啟狀態(tài)機
  • 不進行擁塞控制:不內(nèi)置客戶端或網(wǎng)絡(luò)反饋機制

5. TCP的重傳機制

由于TCP的下層網(wǎng)絡(luò)(網(wǎng)絡(luò)層)可能出現(xiàn)丟失、重復(fù)或失序的情況,TCP協(xié)議提供可靠數(shù)據(jù)傳輸服務(wù)。為保證數(shù)據(jù)傳輸?shù)恼_性,TCP會重傳其認為已丟失(包括報文中的比特錯誤)的包。TCP使用兩套獨立的機制來完成重傳,一是基于時間,二是基于確認信息。

TCP在發(fā)送一個數(shù)據(jù)之后,就開啟一個定時器,若是在這個時間內(nèi)沒有收到發(fā)送數(shù)據(jù)的ACK確認報文,則對該報文進行重傳,在達到一定次數(shù)還沒有成功時放棄并發(fā)送一個復(fù)位信號。

6. TCP的擁塞控制機制

TCP的擁塞控制機制主要是以下四種機制:

  • 慢啟動(慢開始)
  • 擁塞避免
  • 快速重傳
  • 快速恢復(fù)

(1)慢啟動(慢開始)

  • 在開始發(fā)送的時候設(shè)置cwnd = 1(cwnd指的是擁塞窗口)
  • 思路:開始的時候不要發(fā)送大量數(shù)據(jù),而是先測試一下網(wǎng)絡(luò)的擁塞程度,由小到大增加擁塞窗口的大小。
  • 為了防止cwnd增長過大引起網(wǎng)絡(luò)擁塞,設(shè)置一個慢開始門限(ssthresh 狀態(tài)變量)
    • 當(dāng)cnwd < ssthresh,使用慢開始算法
    • 當(dāng)cnwd = ssthresh,既可使用慢開始算法,也可以使用擁塞避免算法
    • 當(dāng)cnwd > ssthresh,使用擁塞避免算法

(2)擁塞避免

  • 擁塞避免未必能夠完全避免擁塞,是說在擁塞避免階段將擁塞窗口控制為按線性增長,使網(wǎng)絡(luò)不容易出現(xiàn)阻塞。
  • 思路: 讓擁塞窗口cwnd緩慢的增大,即每經(jīng)過一個返回時間RTT就把發(fā)送方的擁塞控制窗口加一
  • 無論是在慢開始階段還是在擁塞避免階段,只要發(fā)送方判斷網(wǎng)絡(luò)出現(xiàn)擁塞,就把慢開始門限設(shè)置為出現(xiàn)擁塞時的發(fā)送窗口大小的一半。然后把擁塞窗口設(shè)置為1,執(zhí)行慢開始算法。如圖所示:

image

  • 其中,判斷網(wǎng)絡(luò)出現(xiàn)擁塞的根據(jù)就是沒有收到確認,雖然沒有收到確認可能是其他原因的分組丟失,但是因為無法判定,所以都當(dāng)做擁塞來處理。

(3)快速重傳

  • 快重傳要求接收方在收到一個失序的報文段后就立即發(fā)出重復(fù)確認(為的是使發(fā)送方及早知道有報文段沒有到達對方)。發(fā)送方只要連續(xù)收到三個重復(fù)確認就立即重傳對方尚未收到的報文段,而不必繼續(xù)等待設(shè)置的重傳計時器時間到期。
  • 由于不需要等待設(shè)置的重傳計時器到期,能盡早重傳未被確認的報文段,能提高整個網(wǎng)絡(luò)的吞吐量

(4)快速恢復(fù)

  • 當(dāng)發(fā)送方連續(xù)收到三個重復(fù)確認時,就執(zhí)行“乘法減小”算法,把ssthresh門限減半。但是接下去并不執(zhí)行慢開始算法。
  • 考慮到如果網(wǎng)絡(luò)出現(xiàn)擁塞的話就不會收到好幾個重復(fù)的確認,所以發(fā)送方現(xiàn)在認為網(wǎng)絡(luò)可能沒有出現(xiàn)擁塞。所以此時不執(zhí)行慢開始算法,而是將cwnd設(shè)置為ssthresh的大小,然后執(zhí)行擁塞避免算法。

image

7. TCP的流量控制機制

一般來說,流量控制就是為了讓發(fā)送方發(fā)送數(shù)據(jù)的速度不要太快,要讓接收方來得及接收。TCP采用大小可變的滑動窗口進行流量控制,窗口大小的單位是字節(jié)。這里說的窗口大小其實就是每次傳輸?shù)臄?shù)據(jù)大小。

  • 當(dāng)一個連接建立時,連接的每一端分配一個緩沖區(qū)來保存輸入的數(shù)據(jù),并將緩沖區(qū)的大小發(fā)送給另一端。
  • 當(dāng)數(shù)據(jù)到達時,接收方發(fā)送確認,其中包含了自己剩余的緩沖區(qū)大小。(剩余的緩沖區(qū)空間的大小被稱為窗口,指出窗口大小的通知稱為窗口通告 。接收方在發(fā)送的每一確認中都含有一個窗口通告。)
  • 如果接收方應(yīng)用程序讀數(shù)據(jù)的速度能夠與數(shù)據(jù)到達的速度一樣快,接收方將在每一確認中發(fā)送一個正的窗口通告。
  • 如果發(fā)送方操作的速度快于接收方,接收到的數(shù)據(jù)最終將充滿接收方的緩沖區(qū),導(dǎo)致接收方通告一個零窗口 。發(fā)送方收到一個零窗口通告時,必須停止發(fā)送,直到接收方重新通告一個正的窗口。

8. TCP的可靠傳輸機制

TCP 的可靠傳輸機制是基于連續(xù) ARQ 協(xié)議和滑動窗口協(xié)議的。

TCP 協(xié)議在發(fā)送方維持了一個發(fā)送窗口,發(fā)送窗口以前的報文段是已經(jīng)發(fā)送并確認了的報文段,發(fā)送窗口中包含了已經(jīng)發(fā)送但 未確認的報文段和允許發(fā)送但還未發(fā)送的報文段,發(fā)送窗口以后的報文段是緩存中還不允許發(fā)送的報文段。當(dāng)發(fā)送方向接收方發(fā) 送報文時,會依次發(fā)送窗口內(nèi)的所有報文段,并且設(shè)置一個定時器,這個定時器可以理解為是最早發(fā)送但未收到確認的報文段。 如果在定時器的時間內(nèi)收到某一個報文段的確認回答,則滑動窗口,將窗口的首部向后滑動到確認報文段的后一個位置,此時如 果還有已發(fā)送但沒有確認的報文段,則重新設(shè)置定時器,如果沒有了則關(guān)閉定時器。如果定時器超時,則重新發(fā)送所有已經(jīng)發(fā)送 但還未收到確認的報文段,并將超時的間隔設(shè)置為以前的兩倍。當(dāng)發(fā)送方收到接收方的三個冗余的確認應(yīng)答后,這是一種指示, 說明該報文段以后的報文段很有可能發(fā)生丟失了,那么發(fā)送方會啟用快速重傳的機制,就是當(dāng)前定時器結(jié)束前,發(fā)送所有的已發(fā) 送但確認的報文段。

接收方使用的是累計確認的機制,對于所有按序到達的報文段,接收方返回一個報文段的肯定回答。如果收到了一個亂序的報文 段,那么接方會直接丟棄,并返回一個最近的按序到達的報文段的肯定回答。使用累計確認保證了返回的確認號之前的報文段都 已經(jīng)按序到達了,所以發(fā)送窗口可以移動到已確認報文段的后面。

發(fā)送窗口的大小是變化的,它是由接收窗口剩余大小和網(wǎng)絡(luò)中擁塞程度來決定的,TCP 就是通過控制發(fā)送窗口的長度來控制報文 段的發(fā)送速率。

但是 TCP 協(xié)議并不完全和滑動窗口協(xié)議相同,因為許多的 TCP 實現(xiàn)會將失序的報文段給緩存起來,并且發(fā)生重傳時,只會重 傳一個報文段,因此 TCP 協(xié)議的可靠傳輸機制更像是窗口滑動協(xié)議和選擇重傳協(xié)議的一個混合體。

9. TCP的三次握手和四次揮手

(1)三次握手

image

三次握手(Three-way Handshake)其實就是指建立一個TCP連接時,需要客戶端和服務(wù)器總共發(fā)送3個包。進行三次握手的主要作用就是為了確認雙方的接收能力和發(fā)送能力是否正常、指定自己的初始化序列號為后面的可靠性傳送做準(zhǔn)備。實質(zhì)上其實就是連接服務(wù)器指定端口,建立TCP連接,并同步連接雙方的序列號和確認號,交換TCP窗口大小信息。

剛開始客戶端處于 Closed 的狀態(tài),服務(wù)端處于 Listen 狀態(tài)。

  • 第一次握手:客戶端給服務(wù)端發(fā)一個 SYN 報文,并指明客戶端的初始化序列號 ISN,此時客戶端處于 SYN_SEND 狀態(tài)。

首部的同步位SYN=1,初始序號seq=x,SYN=1的報文段不能攜帶數(shù)據(jù),但要消耗掉一個序號。

  • 第二次握手:服務(wù)器收到客戶端的 SYN 報文之后,會以自己的 SYN 報文作為應(yīng)答,并且也是指定了自己的初始化序列號 ISN。同時會把客戶端的 ISN + 1 作為ACK 的值,表示自己已經(jīng)收到了客戶端的 SYN,此時服務(wù)器處于 SYN_REVD 的狀態(tài)。

在確認報文段中SYN=1,ACK=1,確認號ack=x+1,初始序號seq=y

  • 第三次握手:客戶端收到 SYN 報文之后,會發(fā)送一個 ACK 報文,當(dāng)然,也是一樣把服務(wù)器的 ISN + 1 作為 ACK 的值,表示已經(jīng)收到了服務(wù)端的 SYN 報文,此時客戶端處于 ESTABLISHED 狀態(tài)。服務(wù)器收到 ACK 報文之后,也處于 ESTABLISHED 狀態(tài),此時,雙方已建立起了連接。

確認報文段ACK=1,確認號ack=y+1,序號seq=x+1(初始為seq=x,第二個報文段所以要+1),ACK報文段可以攜帶數(shù)據(jù),不攜帶數(shù)據(jù)則不消耗序號。

那為什么要三次握手呢?兩次不行嗎?

  • 為了確認雙方的接收能力和發(fā)送能力都正常
  • 如果是用兩次握手,則會出現(xiàn)下面這種情況:
如客戶端發(fā)出連接請求,但因連接請求報文丟失而未收到確認,于是客戶端再重傳一次連接請求。后來收到了確認,建立了連接。數(shù)據(jù)傳輸完畢后,就釋放了連接,客戶端共發(fā)出了兩個連接請求報文段,其中第一個丟失,第二個到達了服務(wù)端,但是第一個丟失的報文段只是在某些網(wǎng)絡(luò)結(jié)點長時間滯留了,延誤到連接釋放以后的某個時間才到達服務(wù)端,此時服務(wù)端誤認為客戶端又發(fā)出一次新的連接請求,于是就向客戶端發(fā)出確認報文段,同意建立連接,不采用三次握手,只要服務(wù)端發(fā)出確認,就建立新的連接了,此時客戶端忽略服務(wù)端發(fā)來的確認,也不發(fā)送數(shù)據(jù),則服務(wù)端一致等待客戶端發(fā)送數(shù)據(jù),浪費資源。

簡單來說就是以下三步:

  • 第一次握手:客戶端向服務(wù)端發(fā)送連接請求報文段。該報文段中包含自身的數(shù)據(jù)通訊初始序號。請求發(fā)送后,客戶端便進入 SYN-SENT 狀態(tài)。
  • 第二次握手:服務(wù)端收到連接請求報文段后,如果同意連接,則會發(fā)送一個應(yīng)答,該應(yīng)答中也會包含自身的數(shù)據(jù)通訊初始序號,發(fā)送完成后便進入 SYN-RECEIVED 狀態(tài)。
  • 第三次握手:當(dāng)客戶端收到連接同意的應(yīng)答后,還要向服務(wù)端發(fā)送一個確認報文。客戶端發(fā)完這個報文段后便進入 ESTABLISHED 狀態(tài),服務(wù)端收到這個應(yīng)答后也進入 ESTABLISHED 狀態(tài),此時連接建立成功。

TCP 三次握手的建立連接的過程就是相互確認初始序號的過程,告訴對方,什么樣序號的報文段能夠被正確接收。 第三次握手的作用是客戶端對服務(wù)器端的初始序號的確認。如果只使用兩次握手,那么服務(wù)器就沒有辦法知道自己的序號是否 已被確認。同時這樣也是為了防止失效的請求報文段被服務(wù)器接收,而出現(xiàn)錯誤的情況。

(2)四次揮手

image

剛開始雙方都處于 ESTABLISHED 狀態(tài),假如是客戶端先發(fā)起關(guān)閉請求。四次揮手的過程如下:

  • 第一次揮手: 客戶端會發(fā)送一個 FIN 報文,報文中會指定一個序列號。此時客戶端處于 FIN_WAIT1 狀態(tài)。
即發(fā)出連接釋放報文段(FIN=1,序號seq=u),并停止再發(fā)送數(shù)據(jù),主動關(guān)閉TCP連接,進入FIN_WAIT1(終止等待1)狀態(tài),等待服務(wù)端的確認。
  • 第二次揮手:服務(wù)端收到 FIN 之后,會發(fā)送 ACK 報文,且把客戶端的序列號值 +1 作為 ACK 報文的序列號值,表明已經(jīng)收到客戶端的報文了,此時服務(wù)端處于 CLOSE_WAIT 狀態(tài)。
即服務(wù)端收到連接釋放報文段后即發(fā)出確認報文段(ACK=1,確認號ack=u+1,序號seq=v),服務(wù)端進入CLOSE_WAIT(關(guān)閉等待)狀態(tài),此時的TCP處于半關(guān)閉狀態(tài),客戶端到服務(wù)端的連接釋放??蛻舳耸盏椒?wù)端的確認后,進入FIN_WAIT2(終止等待2)狀態(tài),等待服務(wù)端發(fā)出的連接釋放報文段。
  • 第三次揮手:如果服務(wù)端也想斷開連接了,和客戶端的第一次揮手一樣,發(fā)給 FIN 報文,且指定一個序列號。此時服務(wù)端處于 LAST_ACK 的狀態(tài)。
即服務(wù)端沒有要向客戶端發(fā)出的數(shù)據(jù),服務(wù)端發(fā)出連接釋放報文段(FIN=1,ACK=1,序號seq=w,確認號ack=u+1),服務(wù)端進入LAST_ACK(最后確認)狀態(tài),等待客戶端的確認。
  • 第四次揮手:客戶端收到 FIN 之后,一樣發(fā)送一個 ACK 報文作為應(yīng)答,且把服務(wù)端的序列號值 +1 作為自己 ACK 報文的序列號值,此時客戶端處于 TIME_WAIT 狀態(tài)。需要過一陣子以確保服務(wù)端收到自己的 ACK 報文之后才會進入 CLOSED 狀態(tài),服務(wù)端收到 ACK 報文之后,就處于關(guān)閉連接了,處于 CLOSED 狀態(tài)。
即客戶端收到服務(wù)端的連接釋放報文段后,對此發(fā)出確認報文段(ACK=1,seq=u+1,ack=w+1),客戶端進入TIME_WAIT(時間等待)狀態(tài)。此時TCP未釋放掉,需要經(jīng)過時間等待計時器設(shè)置的時間2MSL后,客戶端才進入CLOSED狀態(tài)。

那為什么需要四次揮手呢?

因為當(dāng)服務(wù)端收到客戶端的SYN連接請求報文后,可以直接發(fā)送SYN+ACK報文。其中ACK報文是用來應(yīng)答的,SYN報文是用來同步的。但是關(guān)閉連接時,當(dāng)服務(wù)端收到FIN報文時,很可能并不會立即關(guān)閉SOCKET,所以只能先回復(fù)一個ACK報文,告訴客戶端,“你發(fā)的FIN報文我收到了”。只有等到我服務(wù)端所有的報文都發(fā)送完了,我才能發(fā)送FIN報文,因此不能一起發(fā)送,故需要四次揮手。

簡單來說就是以下四步:

  • 第一次揮手:若客戶端認為數(shù)據(jù)發(fā)送完成,則它需要向服務(wù)端發(fā)送連接釋放請求。
  • 第二次揮手:服務(wù)端收到連接釋放請求后,會告訴應(yīng)用層要釋放 TCP 鏈接。然后會發(fā)送 ACK 包,并進入 CLOSE_WAIT 狀態(tài),此時表明客戶端到服務(wù)端的連接已經(jīng)釋放,不再接收客戶端發(fā)的數(shù)據(jù)了。但是因為 TCP 連接是雙向的,所以服務(wù)端仍舊可以發(fā)送數(shù)據(jù)給客戶端。
  • 第三次揮手:服務(wù)端如果此時還有沒發(fā)完的數(shù)據(jù)會繼續(xù)發(fā)送,完畢后會向客戶端發(fā)送連接釋放請求,然后服務(wù)端便進入 LAST-ACK 狀態(tài)。
  • 第四次揮手:客戶端收到釋放請求后,向服務(wù)端發(fā)送確認應(yīng)答,此時客戶端進入 TIME-WAIT 狀態(tài)。該狀態(tài)會持續(xù) 2MSL(最大段生存期,指報文段在網(wǎng)絡(luò)中生存的時間,超時會被拋棄) 時間,若該時間段內(nèi)沒有服務(wù)端的重發(fā)請求的話,就進入 CLOSED 狀態(tài)。當(dāng)服務(wù)端收到確認應(yīng)答后,也便進入 CLOSED 狀態(tài)。

TCP 使用四次揮手的原因是因為 TCP 的連接是全雙工的,所以需要雙方分別釋放到對方的連接,單獨一方的連接釋放,只代 表不能再向?qū)Ψ桨l(fā)送數(shù)據(jù),連接處于的是半釋放的狀態(tài)。

最后一次揮手中,客戶端會等待一段時間再關(guān)閉的原因,是為了防止發(fā)送給服務(wù)器的確認報文段丟失或者出錯,從而導(dǎo)致服務(wù)器 端不能正常關(guān)閉。

10. TCP粘包是怎么回事,如何處理?

默認情況下, TCP 連接會啟?延遲傳送算法 (Nagle 算法), 在數(shù)據(jù)發(fā)送之前緩存他們. 如果短時間有多個數(shù)據(jù)發(fā)送, 會緩沖到?起作?次發(fā)送 (緩沖大小見 socket.bufferSize ), 這樣可以減少 IO 消耗提?性能.

如果是傳輸?件的話, 那么根本不?處理粘包的問題, 來?個包拼?個包就好了。但是如果是多條消息, 或者是別的?途的數(shù)據(jù)那么就需要處理粘包.

下面看?個例?, 連續(xù)調(diào)?兩次 send 分別發(fā)送兩段數(shù)據(jù) data1 和 data2, 在接收端有以下?種常?的情況:

A. 先接收到 data1, 然后接收到 data2 .

B. 先接收到 data1 的部分?jǐn)?shù)據(jù), 然后接收到 data1 余下的部分以及 data2 的全部.

C. 先接收到了 data1 的全部數(shù)據(jù)和 data2 的部分?jǐn)?shù)據(jù), 然后接收到了 data2 的余下的數(shù)據(jù).

D. ?次性接收到了 data1 和 data2 的全部數(shù)據(jù).

其中的 BCD 就是我們常?的粘包的情況. ?對于處理粘包的問題, 常?的解決?案有:

  • 多次發(fā)送之前間隔?個等待時間:只需要等上?段時間再進?下?次 send 就好, 適?于交互頻率特別低的場景. 缺點也很明顯, 對于?較頻繁的場景??傳輸效率實在太低,不過?乎不?做什么處理.
  • 關(guān)閉Nagle算法:關(guān)閉 Nagle 算法, 在 Node.js 中你可以通過 socket.setNoDelay() ?法來關(guān)閉 Nagle 算法, 讓每?次 send 都不緩沖直接發(fā)送。該?法?較適?于每次發(fā)送的數(shù)據(jù)都?較? (但不是?件那么?), 并且頻率不是特別?的場景。如果是每次發(fā)送的數(shù)據(jù)量?較?, 并且頻率特別?的, 關(guān)閉 Nagle 純屬?廢武功。另外, 該?法不適?于?絡(luò)較差的情況, 因為 Nagle 算法是在服務(wù)端進?的包合并情況, 但是如果短時間內(nèi)客戶端的?絡(luò)情況不好, 或者應(yīng)?層由于某些原因不能及時將 TCP 的數(shù)據(jù) recv, 就會造成多個包在客戶端緩沖從?粘包的情況。 (如果是在穩(wěn)定的機房內(nèi)部通信那么這個概率是?較?可以選擇忽略的)
  • 進?封包/拆包:封包/拆包是?前業(yè)內(nèi)常?的解決?案了。即給每個數(shù)據(jù)包在發(fā)送之前, 于其前/后放?些有特征的數(shù)據(jù), 然后收到數(shù)據(jù)的時 候根據(jù)特征數(shù)據(jù)分割出來各個數(shù)據(jù)包。

11. 為什么udp不會粘包?

  • TCP協(xié)議是?向流的協(xié)議,UDP是?向消息的協(xié)議。UDP段都是?條消息,應(yīng)?程序必須以消息為單位提取數(shù)據(jù),不能?次提取任意字節(jié)的數(shù)據(jù)
  • UDP具有保護消息邊界,在每個UDP包中就有了消息頭(消息來源地址,端?等信息),這樣對于接收端來說就容易進?區(qū)分處理了。傳輸協(xié)議把數(shù)據(jù)當(dāng)作?條獨?的消息在?上傳輸,接收端只能接收獨?的消息。接收端?次只能接收發(fā)送端發(fā)出的?個數(shù)據(jù)包,如果?次接受數(shù)據(jù)的???于發(fā)送端?次發(fā)送的數(shù)據(jù)??,就會丟失?部分?jǐn)?shù)據(jù),即使丟失,接受端也不會分兩次去接收。

七、WebSocket


1. 對 WebSocket 的理解

WebSocket是HTML5提供的一種瀏覽器與服務(wù)器進行全雙工通訊的網(wǎng)絡(luò)技術(shù),屬于應(yīng)用層協(xié)議。它基于TCP傳輸協(xié)議,并復(fù)用HTTP的握手通道。瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接, 并進行雙向數(shù)據(jù)傳輸。

WebSocket 的出現(xiàn)就解決了半雙工通信的弊端。它最大的特點是:服務(wù)器可以向客戶端主動推動消息,客戶端也可以主動向服務(wù)器推送消息。

WebSocket原理:客戶端向 WebSocket 服務(wù)器通知(notify)一個帶有所有接收者ID(recipients IDs)的事件(event),服務(wù)器接收后立即通知所有活躍的(active)客戶端,只有ID在接收者ID序列中的客戶端才會處理這個事件。

WebSocket 特點的如下:

  • 支持雙向通信,實時性更強
  • 可以發(fā)送文本,也可以發(fā)送二進制數(shù)據(jù)‘’
  • 建立在TCP協(xié)議之上,服務(wù)端的實現(xiàn)比較容易
  • 數(shù)據(jù)格式比較輕量,性能開銷小,通信高效
  • 沒有同源限制,客戶端可以與任意服務(wù)器通信
  • 協(xié)議標(biāo)識符是ws(如果加密,則為wss),服務(wù)器網(wǎng)址就是 URL
  • 與 HTTP 協(xié)議有著良好的兼容性。默認端口也是80和443,并且握手階段采用 HTTP 協(xié)議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務(wù)器。

Websocket的使用方法如下:

在客戶端中:

// 在index.html中直接寫WebSocket,設(shè)置服務(wù)端的端口號為 9999
let ws = new WebSocket('ws://localhost:9999');
// 在客戶端與服務(wù)端建立連接后觸發(fā)
ws.onopen = function() {
    console.log("Connection open."); 
    ws.send('hello');
};
// 在服務(wù)端給客戶端發(fā)來消息的時候觸發(fā)
ws.onmessage = function(res) {
    console.log(res);       // 打印的是MessageEvent對象
    console.log(res.data);  // 打印的是收到的消息
};
// 在客戶端與服務(wù)端建立關(guān)閉后觸發(fā)
ws.onclose = function(evt) {
  console.log("Connection closed.");
}; 

2. 即時通訊的實現(xiàn):短輪詢、長輪詢、SSE 和 WebSocket 間的區(qū)別?

短輪詢和長輪詢的目的都是用于實現(xiàn)客戶端和服務(wù)器端的一個即時通訊。

短輪詢的基本思路:瀏覽器每隔一段時間向瀏覽器發(fā)送 http 請求,服務(wù)器端在收到請求后,不論是否有數(shù)據(jù)更新,都直接進行響應(yīng)。這種方式實現(xiàn)的即時通信,本質(zhì)上還是瀏覽器發(fā)送請求,服務(wù)器接受請求的一個過程,通過讓客戶端不斷的進行請求,使得客戶端能夠模擬實時地收到服務(wù)器端的數(shù)據(jù)的變化。這種方式的優(yōu)點是比較簡單,易于理解。缺點是這種方式由于需要不斷的建立 http 連接,嚴(yán)重浪費了服務(wù)器端和客戶端的資源。當(dāng)用戶增加時,服務(wù)器端的壓力就會變大,這是很不合理的。

長輪詢的基本思路:首先由客戶端向服務(wù)器發(fā)起請求,當(dāng)服務(wù)器收到客戶端發(fā)來的請求后,服務(wù)器端不會直接進行響應(yīng),而是先將這個請求掛起,然后判斷服務(wù)器端數(shù)據(jù)是否有更新。如果有更新,則進行響應(yīng),如果一直沒有數(shù)據(jù),則到達一定的時間限制才返回。客戶端 JavaScript 響應(yīng)處理函數(shù)會在處理完服務(wù)器返回的信息后,再次發(fā)出請求,重新建立連接。長輪詢和短輪詢比起來,它的優(yōu)點是明顯減少了很多不必要的 http 請求次數(shù),相比之下節(jié)約了資源。長輪詢的缺點在于,連接掛起也會導(dǎo)致資源的浪費。

SSE 的基本思想:服務(wù)器使用流信息向服務(wù)器推送信息。嚴(yán)格地說,http 協(xié)議無法做到服務(wù)器主動推送信息。但是,有一種變通方法,就是服務(wù)器向客戶端聲明,接下來要發(fā)送的是流信息。也就是說,發(fā)送的不是一次性的數(shù)據(jù)包,而是一個數(shù)據(jù)流,會連續(xù)不斷地發(fā)送過來。這時,客戶端不會關(guān)閉連接,會一直等著服務(wù)器發(fā)過來的新的數(shù)據(jù)流,視頻播放就是這樣的例子。SSE 就是利用這種機制,使用流信息向瀏覽器推送信息。它基于 http 協(xié)議,目前除了 IE/Edge,其他瀏覽器都支持。它相對于前面兩種方式來說,不需要建立過多的 http 請求,相比之下節(jié)約了資源。

WebSocket 是 HTML5 定義的一個新協(xié)議議,與傳統(tǒng)的 http 協(xié)議不同,該協(xié)議允許由服務(wù)器主動的向客戶端推送信息。使用 WebSocket 協(xié)議的缺點是在服務(wù)器端的配置比較復(fù)雜。WebSocket 是一個全雙工的協(xié)議,也就是通信雙方是平等的,可以相互發(fā)送消息,而 SSE 的方式是單向通信的,只能由服務(wù)器端向客戶端推送信息,如果客戶端需要發(fā)送信息就是屬于下一個 http 請求了。

上面的四個通信協(xié)議,前三個都是基于HTTP協(xié)議的。

對于這四種即使通信協(xié)議,從性能的角度來看:

WebSocket > 長連接(SEE) > 長輪詢 > 短輪詢

但是,我們?nèi)绻紤]瀏覽器的兼容性問題,順序就恰恰相反了:

短輪詢 > 長輪詢 > 長連接(SEE) > WebSocket

所以,還是要根據(jù)具體的使用場景來判斷使用哪種方式。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號