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

2023-02-17 10:51 更新


一、HTTP協(xié)議


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

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

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

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

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

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

HTTP Request Header 常見的請(qǐng)求頭:

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

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

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

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

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

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

(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)站訪問速度,對(duì)之前訪問的部分頁面指定緩存機(jī)制,當(dāng)客戶端在此對(duì)這些頁面進(jìn)行請(qǐng)求,服務(wù)器會(huì)根據(jù)緩存內(nèi)容判斷頁面與之前是否相同,若相同便直接返回304,此時(shí)客戶端調(diào)用緩存內(nèi)容,不必進(jìn)行二次下載。

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

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

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

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

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

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

5. 常見的HTTP請(qǐng)求方法

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

6. OPTIONS請(qǐng)求方法及使用場景

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

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

OPTIONS請(qǐng)求方法的主要用途有兩個(gè):

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

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

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

  • 連接方面,http1.0 默認(rèn)使用非持久連接,而 http1.1 默認(rèn)使用持久連接。http1.1 通過使用持久連接來使多個(gè) http 請(qǐng)求復(fù)用同一個(gè) TCP 連接,以此來避免使用非持久連接時(shí)每次需要建立連接的時(shí)延。
  • 資源請(qǐng)求方面,在 http1.0 中,存在一些浪費(fèi)帶寬的現(xiàn)象,例如客戶端只是需要某個(gè)對(duì)象的一部分,而服務(wù)器卻將整個(gè)對(duì)象送過來了,并且不支持?jǐn)帱c(diǎn)續(xù)傳功能,http1.1 則在請(qǐng)求頭引入了 range 頭域,它允許只請(qǐng)求資源的某個(gè)部分,即返回碼是 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 中認(rèn)為每臺(tái)服務(wù)器都綁定一個(gè)唯一的 IP 地址,因此,請(qǐng)求消息中的 URL 并沒有傳遞主機(jī)名(hostname)。但隨著虛擬主機(jī)技術(shù)的發(fā)展,在一臺(tái)物理服務(wù)器上可以存在多個(gè)虛擬主機(jī),并且它們共享一個(gè)IP地址。因此有了 host 字段,這樣就可以將請(qǐng)求發(fā)往到同一臺(tái)服務(wù)器上的不同網(wǎng)站。
  • http1.1 相對(duì)于 http1.0 還新增了很多請(qǐng)求方法,如 PUT、HEAD、OPTIONS 等。

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

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

【1】隊(duì)頭堵塞:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

(5)TCP三次握手:下面是 TCP 建立連接的三次握手的過程,首先客戶端向服務(wù)器發(fā)送一個(gè) SYN 連接請(qǐng)求報(bào)文段和一個(gè)隨機(jī)序號(hào),服務(wù)端接收到請(qǐng)求后向服務(wù)器端發(fā)送一個(gè) SYN ACK報(bào)文段,確認(rèn)連接請(qǐng)求,并且也向客戶端發(fā)送一個(gè)隨機(jī)序號(hào)。客戶端接收服務(wù)器的確認(rèn)應(yīng)答后,進(jìn)入連接建立的狀態(tài),同時(shí)向服務(wù)器也發(fā)送一個(gè)ACK 確認(rèn)報(bào)文段,服務(wù)器端接收到確認(rèn)后,也進(jìn)入連接建立狀態(tài),此時(shí)雙方的連接就建立起來了。

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

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

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

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

12. 對(duì)keep-alive的理解

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

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

Keep-Alive的建立過程

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

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

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

客戶端請(qǐng)求斷開連接過程

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

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

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

開啟Keep-Alive的缺點(diǎn)

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

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

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

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

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

具體來說:

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

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


15. HTTP請(qǐng)求報(bào)文的是什么樣的?

請(qǐng)求報(bào)?有4部分組成:

  • 請(qǐng)求?
  • 請(qǐng)求頭部
  • 空?
  • 請(qǐng)求體

image.png

其中:

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

(2)請(qǐng)求頭部:請(qǐng)求頭部由關(guān)鍵字/值對(duì)組成,每??對(duì),關(guān)鍵字和值?英?冒號(hào)“:”分隔

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

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

image.png

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

請(qǐng)求報(bào)?有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)點(diǎn)和缺點(diǎn)

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

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

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

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

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

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

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

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

18. 說一下HTTP 3.0

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

image

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

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

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

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

  • 長連接

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

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

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

對(duì)于不同版本的采用不同的連接方式:

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

image

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

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

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

  • 隊(duì)頭堵塞

HTTP 傳輸?shù)膱?bào)文必須是一發(fā)一收,但是,里面的任務(wù)被放在一個(gè)任務(wù)隊(duì)列中串行執(zhí)行,一旦隊(duì)首的請(qǐng)求處理太慢,就會(huì)阻塞后面請(qǐng)求的處理。這就是HTTP隊(duì)頭阻塞問題。

隊(duì)頭阻塞的解決方案:

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

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

20. URL有哪些組成部分

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

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

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

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

強(qiáng)緩存:

  • Expires
  • Cache-Control

協(xié)商緩存:

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

二、HTTPS協(xié)議


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

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

image

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

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

2. TLS/SSL的工作原理

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

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

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

image

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

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

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

(2)對(duì)稱加密

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

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

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

(3)非對(duì)稱加密

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

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

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

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

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

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

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

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

image

4. HTTPS通信(握手)過程

HTTPS的通信過程如下:

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

5. HTTPS的特點(diǎn)

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

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

HTTPS的缺點(diǎn)如下:

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

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

先理解兩個(gè)概念:

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

\1. 私鑰 + 公鑰= 密鑰對(duì)

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

\3. 因?yàn)橥ㄐ烹p?的??都有?套??的密鑰對(duì),通信之前雙?會(huì)先把??的公鑰都先發(fā)給對(duì)?

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

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

解決?案:

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

此時(shí)?帶來?個(gè)問題,中間?問題:

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

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

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

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

三、HTTP狀態(tài)碼


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

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

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

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

(1)200 OK

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

(2)204 No Content

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

(3)206 Partial Content

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

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

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

(1)301 Moved Permanently

永久重定向。

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

使用場景:

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

(2)302 Found

臨時(shí)重定向。

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

使用場景:

  • 當(dāng)我們?cè)谧龌顒?dòng)時(shí),登錄到首頁自動(dòng)重定向,進(jìn)入活動(dòng)頁面。
  • 未登陸的用戶訪問用戶中心重定向到登錄頁面。
  • 訪問404頁面重新定向到首頁。

(3)303 See Other

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

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

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

注意:

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

(4)304 Not Modified

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

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

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

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

(5)307 Temporary Redirect

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

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

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

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

(1)400 Bad Request

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

(2)401 Unauthorized

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

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

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

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

(3)403 Forbidden

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

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

  • 403.1 - 執(zhí)行訪問被禁止。
  • 403.2 - 讀訪問被禁止。
  • 403.3 - 寫訪問被禁止。
  • 403.4 - 要求 SSL。
  • 403.5 - 要求 SSL 128。
  • 403.6 - IP 地址被拒絕。
  • 403.7 - 要求客戶端證書。
  • 403.8 - 站點(diǎn)訪問被拒絕。
  • 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í)行所請(qǐng)求的 URL。這個(gè)錯(cuò)誤代碼為 IIS 6.0 所專用。
  • 403.19 - 不能為這個(gè)應(yīng)用程序池中的客戶端執(zhí)行 CGI。這個(gè)錯(cuò)誤代碼為 IIS 6.0 所專用。
  • 403.20 - Passport 登錄失敗。這個(gè)錯(cuò)誤代碼為 IIS 6.0 所專用。

(4)404 Not Found

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

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

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

(5)405 Method Not Allowed

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

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

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

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

(1)500 Internal Server Error

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

(2)502 Bad Gateway

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

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

(3)503 Service Unavailable

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

使用場景:

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

(4)504 Gateway Timeout

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

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

5. 總結(jié)

(1)2XX 成功

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

(2)3XX 重定向

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

(3)4XX 客戶端錯(cuò)誤

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

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

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

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

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

四、DNS協(xié)議介紹


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

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

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

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

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

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

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

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

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

3. DNS完整的查詢過程

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

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

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

4. 迭代查詢與遞歸查詢

實(shí)際上,DNS解析是一個(gè)包含迭代查詢和遞歸查詢的過程。

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

一般我們向本地 DNS 服務(wù)器發(fā)送請(qǐng)求的方式就是遞歸查詢,因?yàn)槲覀冎恍枰l(fā)出一次請(qǐng)求,然后本地 DNS 服務(wù)器返回給我 們最終的請(qǐng)求結(jié)果。而本地 DNS 服務(wù)器向其他域名服務(wù)器請(qǐng)求的過程是迭代查詢的過程,因?yàn)槊恳淮斡蛎?wù)器只返回單次 查詢的結(jié)果,下一級(jí)的查詢由本地 DNS 服務(wù)器自己進(jìn)行。

5. DNS 記錄和報(bào)文

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

(Name,Value,Type,TTL)

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

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

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

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


1. OSI七層模型

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

image

(1)應(yīng)用層

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

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

(2)表示層

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

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

(3)會(huì)話層

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

(4)傳輸層

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

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

本層通過 IP尋址來建立兩個(gè)節(jié)點(diǎn)之間的連接,為源端的運(yùn)輸層送來的分組,選擇合適的路由和交換節(jié)點(diǎn),正確無誤地按照地址傳送給目的端的運(yùn)輸層。就是通常說的 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ì),并進(jìn)行差錯(cuò)檢測。

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

(7)物理層

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

OSI七層模型通信特點(diǎn):對(duì)等通信

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

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

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

image

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

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

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

image

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

image

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

image.png

六、TCP與UDP


1. TCP 和 UDP的概念及特點(diǎn)

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

(1)UDP

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

它的特點(diǎn)如下:

1)面向無連接

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

具體來說就是:

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

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

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

3)面向報(bào)文

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

4)不可靠性

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

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

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

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

image

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

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

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

(2)TCP

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

它有以下幾個(gè)特點(diǎn):

1)面向連接

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

2)僅支持單播傳輸

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

3)面向字節(jié)流

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

4)可靠傳輸

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

5)提供擁塞控制

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

6)提供全雙工通信

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

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

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

3. TCP和UDP的使用場景

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

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

UDP在傳輸數(shù)據(jù)之前不需要先建立連接,遠(yuǎn)地主機(jī)的運(yùn)輸層在接收到UDP報(bào)文后,不需要確認(rèn),提供不可靠交付。總結(jié)就以下四點(diǎn):

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

5. TCP的重傳機(jī)制

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

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

6. TCP的擁塞控制機(jī)制

TCP的擁塞控制機(jī)制主要是以下四種機(jī)制:

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

(1)慢啟動(dòng)(慢開始)

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

(2)擁塞避免

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

image

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

(3)快速重傳

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

(4)快速恢復(fù)

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

image

7. TCP的流量控制機(jī)制

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

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

8. TCP的可靠傳輸機(jī)制

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

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

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

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

但是 TCP 協(xié)議并不完全和滑動(dòng)窗口協(xié)議相同,因?yàn)樵S多的 TCP 實(shí)現(xiàn)會(huì)將失序的報(bào)文段給緩存起來,并且發(fā)生重傳時(shí),只會(huì)重 傳一個(gè)報(bào)文段,因此 TCP 協(xié)議的可靠傳輸機(jī)制更像是窗口滑動(dòng)協(xié)議和選擇重傳協(xié)議的一個(gè)混合體。

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

(1)三次握手

image

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

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

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

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

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

在確認(rèn)報(bào)文段中SYN=1,ACK=1,確認(rèn)號(hào)ack=x+1,初始序號(hào)seq=y

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

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

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

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

簡單來說就是以下三步:

  • 第一次握手:客戶端向服務(wù)端發(fā)送連接請(qǐng)求報(bào)文段。該報(bào)文段中包含自身的數(shù)據(jù)通訊初始序號(hào)。請(qǐng)求發(fā)送后,客戶端便進(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)客戶端收到連接同意的應(yīng)答后,還要向服務(wù)端發(fā)送一個(gè)確認(rèn)報(bào)文??蛻舳税l(fā)完這個(gè)報(bào)文段后便進(jìn)入 ESTABLISHED 狀態(tài),服務(wù)端收到這個(gè)應(yīng)答后也進(jìn)入 ESTABLISHED 狀態(tài),此時(shí)連接建立成功。

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

(2)四次揮手

image

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

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

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

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

簡單來說就是以下四步:

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

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

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

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

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

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

下面看?個(gè)例?, 連續(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 就是我們常?的粘包的情況. ?對(duì)于處理粘包的問題, 常?的解決?案有:

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

11. 為什么udp不會(huì)粘包?

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

七、WebSocket


1. 對(duì) WebSocket 的理解

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

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

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

WebSocket 特點(diǎn)的如下:

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

Websocket的使用方法如下:

在客戶端中:

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

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

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

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

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

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

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

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

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

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

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

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

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


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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)