1 述
- WebSocket是一種網(wǎng)絡(luò)通信協(xié)議
- WebSocket 協(xié)議在2008年誕生,2011年成為國際標(biāo)準(zhǔn)。
- HTML5開始提供的一種瀏覽器與服務(wù)器進(jìn)行全雙工通訊的網(wǎng)絡(luò)技術(shù),屬于應(yīng)用層協(xié)議。它基于TCP傳輸協(xié)議,并復(fù)用HTTP的握手通道,可以傳輸基于消息的文本和二進(jìn)制數(shù)據(jù)。
- 兩端都可以隨時(shí)向另一端發(fā)送數(shù)據(jù)。
- 任何事物都不是完美的,設(shè)計(jì)限制和性能權(quán)衡始終會(huì)有,利用WebSocket 也不例外,在提供自定義數(shù)據(jù)交換協(xié)議同時(shí),也不再享有在一些本由瀏覽器提供的服務(wù)和優(yōu)化,如狀態(tài)管理、壓縮、緩存等。
2websocket對(duì)比http
2.1 雙向通信
Http 有 Keep-Alive
- HTTP1.1 默認(rèn)使用持久連接(persistent connection),在一個(gè) TCP 連接上也可以傳輸多個(gè) Request/Response 消息對(duì),但是 HTTP 的基本模型還是一個(gè) Request 對(duì)應(yīng)一個(gè) Response。
- 在雙向通信(客戶端要向服務(wù)器傳送數(shù)據(jù),同時(shí)服務(wù)器也需要實(shí)時(shí)的向客戶端傳送信息,一個(gè)聊天系統(tǒng)就是典型的雙向通信)時(shí)一般會(huì)使用這樣幾種解決方案:
- 1.輪詢(polling),輪詢就會(huì)造成對(duì)網(wǎng)絡(luò)和通信雙方的資源的浪費(fèi),且非實(shí)時(shí)。
- 2.長(zhǎng)輪詢,?長(zhǎng)輪詢主要是發(fā)出一個(gè)HTTP請(qǐng)求到服務(wù)器,然后保持連接打開以允許服務(wù)器在稍后的時(shí)間響應(yīng)(由服務(wù)器確定)。
- 3.長(zhǎng)連接HTTP 的長(zhǎng)連接,本質(zhì)上還是 Request/Response 消息對(duì),仍然會(huì)造成資源的浪費(fèi)、實(shí)時(shí)性不強(qiáng)等問題
2.2相同點(diǎn)
- 都是基于 TCP 的應(yīng)用層協(xié)議
- 都使用 Request/Response 模型進(jìn)行連接的建立
- 在連接的建立過程中對(duì)錯(cuò)誤的處理方式相同,在這個(gè)階段 WS 可能返回和 HTTP 相同的返回碼
- 都可以在網(wǎng)絡(luò)中傳輸數(shù)據(jù)
2.3 不同點(diǎn)
- WS 使用 HTTP 來建立連接,但是定義了一系列新的 header 域,這些域在 HTTP 中并不會(huì)使用
- WS 的連接不能通過中間人來轉(zhuǎn)發(fā),它必須是一個(gè)直接連接
- WS 連接建立之后,通信雙方都可以在任何時(shí)刻向另一方發(fā)送數(shù)據(jù)
- WS 連接建立之后,數(shù)據(jù)的傳輸使用幀來傳遞,不再需要 Request 消息
- WS 的數(shù)據(jù)幀有序
2 Socket 與 WebSocket 的關(guān)系
Socket 其實(shí)并不是一個(gè)協(xié)議,它工作在 OSI 模型會(huì)話層(第5層),是為了方便大家直接使用更底層協(xié)議(一般是 TCP或 UDP)而存在的一個(gè)抽象層。
2 和 TCP 以及 HTTP 之間的關(guān)系
WebSocket 是一個(gè)獨(dú)立的基于 TCP 的協(xié)議,它與 HTTP 之間的唯一關(guān)系就是它的握手請(qǐng)求可以作為一個(gè)升級(jí)請(qǐng)求(Upgrade request)經(jīng)由 HTTP 服務(wù)器解釋(也就是可以使用 Nginx 反向代理一個(gè) WebSocket)。
默認(rèn)情況下,WebSocket 協(xié)議使用 80 端口作為一般請(qǐng)求的端口,端口 443 作為基于傳輸加密層連(TLS)RFC2818 接的端口
3 優(yōu)點(diǎn)
說到優(yōu)點(diǎn),這里的對(duì)比參照物是HTTP協(xié)議,概括地說就是:支持雙向通信,更靈活,更高效,可擴(kuò)展性更好。
具體優(yōu)化如下:
- 1)支持雙向通信,實(shí)時(shí)性更強(qiáng);
- 2)更好的二進(jìn)制支持;
- 3)較少的控制開銷:
- 連接創(chuàng)建后,ws客戶端、服務(wù)端進(jìn)行數(shù)據(jù)交換時(shí),協(xié)議控制的數(shù)據(jù)包頭部較小。在不包含頭部的情況下,服務(wù)端到客戶端的包頭只有2~10字節(jié)(取決于數(shù)據(jù)包長(zhǎng)度),客戶端到服務(wù)端的的話,需要加上額外的4字節(jié)的掩碼。而HTTP協(xié)議每次通信都需要攜帶完整的頭部;
- 4)支持?jǐn)U展:
- ws協(xié)議定義了擴(kuò)展,用戶可以擴(kuò)展協(xié)議,或者實(shí)現(xiàn)自定義的子協(xié)議(比如支持自定義壓縮算法等)。
子協(xié)議
在使用 WebSocket 協(xié)議連接到一個(gè) WebSocket 服務(wù)器時(shí),客戶端可以指定其 Sec-WebSocket-Protocol 為其所期望采用的子協(xié)議集合,而服務(wù)端則可以在此集合中選取一個(gè)并返回給客戶端。
作為服務(wù)端,必須確保選的是客戶端握手請(qǐng)求中的幾個(gè)子協(xié)議中的一個(gè):
Sec-WebSocket-Protocol: chat
4 建立連接
- WebSocket復(fù)用了HTTP的握手通道。具體指的是,客戶端通過HTTP請(qǐng)求與WebSocket服務(wù)端協(xié)商升級(jí)協(xié)議。協(xié)議升級(jí)完成后,后續(xù)的數(shù)據(jù)交換則遵照WebSocket的協(xié)議。
4.1 客戶端:申請(qǐng)協(xié)議升級(jí)
首先,客戶端發(fā)起協(xié)議升級(jí)請(qǐng)求。可以看到,采用的是標(biāo)準(zhǔn)的HTTP報(bào)文格式,且只支持GET方法:

GET / HTTP/1.1
Host: localhost:8080
Origin: [url=http://127.0.0.1:3000]http://127.0.0.1:3000[/url]
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: w4v7O6xFTi36lq3RNcgctw==
重點(diǎn)請(qǐng)求首部意義如下:
Connection: Upgrade:表示要升級(jí)協(xié)議
Upgrade: websocket:表示要升級(jí)到websocket協(xié)議。
Sec-WebSocket-Version: 13:表示websocket的版本。如果服務(wù)端不支持該版本,需要返回一個(gè)Sec-WebSocket-Versionheader,里面包含服務(wù)端支持的版本號(hào)。
Sec-WebSocket-Key:與后面服務(wù)端響應(yīng)首部的Sec-WebSocket-Accept是配套的,提供基本的防護(hù),比如惡意的連接,或者無意的連接。
注意:上面請(qǐng)求省略了部分非重點(diǎn)請(qǐng)求首部。由于是標(biāo)準(zhǔn)的HTTP請(qǐng)求,類似Host、Origin、Cookie等請(qǐng)求首部會(huì)照常發(fā)送。在握手階段,可以通過相關(guān)請(qǐng)求首部進(jìn)行 安全限制、權(quán)限校驗(yàn)等。
4.2 服務(wù)端:響應(yīng)協(xié)議升級(jí)
任何其他的非 101 表示 WebSocket 握手還沒有結(jié)束,客戶端需要使用原有的 HTTP 的方式去響應(yīng)那些狀態(tài)碼。
服務(wù)端返回內(nèi)容如下,狀態(tài)代碼101表示協(xié)議切換:
HTTP/1.1 101 Switching Protocols
Connection:Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: Oy4NRAQ13jhfONC7bP8dTKb4PTU=
到此完成協(xié)議升級(jí),后續(xù)的數(shù)據(jù)交互都按照新的協(xié)議來。
備注:每個(gè)header都以\r\n結(jié)尾,并且最后一行加上一個(gè)額外的空行\(zhòng)r\n。此外,服務(wù)端回應(yīng)的HTTP狀態(tài)碼只能在握手階段使用。過了握手階段后,就只能采用特定的錯(cuò)誤碼。
4.3 Sec-WebSocket-Accept的計(jì)算
- Sec-WebSocket-Accept根據(jù)客戶端請(qǐng)求首部的Sec-WebSocket-Key計(jì)算出來。
計(jì)算公式為:- 1)將Sec-WebSocket-Key跟258EAFA5-E914-47DA-95CA-C5AB0DC85B11拼接;
- 2)通過SHA1計(jì)算出摘要,并轉(zhuǎn)成base64字符串。
4.4 關(guān)閉握手
- 任意一端都可以選擇關(guān)閉握手過程。
需要關(guān)閉握手的一方通過發(fā)送一個(gè)特定的控制序列去開始一個(gè)關(guān)閉握手的過程。- 一端一旦接受到了來自另一端的請(qǐng)求關(guān)閉控制幀后,接收到關(guān)閉請(qǐng)求的一端如果還沒有返回一個(gè)作為響應(yīng)的關(guān)閉幀的話,那么它需要先發(fā)送一個(gè)關(guān)閉幀。
- 在接受到了對(duì)方響應(yīng)的關(guān)閉幀之后,發(fā)起關(guān)閉請(qǐng)求的那一端就可以關(guān)閉連接了。
- 在發(fā)送了請(qǐng)求關(guān)閉控制序列之后,發(fā)送請(qǐng)求的一端將不可以再發(fā)送其他的數(shù)據(jù)內(nèi)容;
- 同樣的,一但接收到了一端的請(qǐng)求關(guān)閉控制序列之后,來自那一端的其他數(shù)據(jù)內(nèi)容將被忽略。
- 注意這里的說的是數(shù)據(jù)內(nèi)容,控制幀還是可以響應(yīng)的。
- 兩邊同時(shí)發(fā)起關(guān)閉請(qǐng)求也是可以的。
作者:mconintet
鏈接:http://www.itdecent.cn/p/867274a5e054
來源:簡(jiǎn)書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
5 數(shù)據(jù)幀格式
- 客戶端、服務(wù)端數(shù)據(jù)的交換,離不開數(shù)據(jù)幀格式的定義。因此,在實(shí)際講解數(shù)據(jù)交換之前,我們先來看下WebSocket的數(shù)據(jù)幀格式。
- WebSocket客戶端、服務(wù)端通信的最小單位是幀(frame),由1個(gè)或多個(gè)幀組成一條完整的消息(message)。
詳情如下:- 發(fā)送端:將消息切割成多個(gè)幀,并發(fā)送給服務(wù)端;
- 接收端:接收消息幀,并將關(guān)聯(lián)的幀重新組裝成完整的消息。
5.1 數(shù)據(jù)幀格式概覽
- 從左到右,單位是比特。比如FIN、RSV1各占據(jù)1比特,opcode占據(jù)4比特;
- 內(nèi)容包括了標(biāo)識(shí)、操作代碼、掩碼、數(shù)據(jù)、數(shù)據(jù)長(zhǎng)度等。

5.2 數(shù)據(jù)幀格式詳解
- FIN:1個(gè)比特
如果是1,表示這是消息(message)的最后一個(gè)分片(fragment),如果是0,表示不是是消息(message)的最后一個(gè)分片(fragment)。
- RSV1, RSV2, RSV3:各占1個(gè)比特
一般情況下全為0。當(dāng)客戶端、服務(wù)端協(xié)商采用WebSocket擴(kuò)展時(shí),這三個(gè)標(biāo)志位可以非0,且值的含義由擴(kuò)展進(jìn)行定義。如果出現(xiàn)非零的值,且并沒有采用WebSocket擴(kuò)展,連接出錯(cuò)。
- Opcode: 4個(gè)比特
- 操作代碼,Opcode的值決定了應(yīng)該如何解析后續(xù)的數(shù)據(jù)載荷(data payload)。如果操作代碼是不認(rèn)識(shí)的,那么接收端應(yīng)該斷開連接(fail the connection)??蛇x的操作代碼如下:
- %x0:表示一個(gè)延續(xù)幀。當(dāng)Opcode為0時(shí),表示本次數(shù)據(jù)傳輸采用了數(shù)據(jù)分片,當(dāng)前收到的數(shù)據(jù)幀為其中一個(gè)數(shù)據(jù)分片;
- %x1:表示這是一個(gè)文本幀(frame);
- %x2:表示這是一個(gè)二進(jìn)制幀(frame);
- %x3-7:保留的操作代碼,用于后續(xù)定義的非控制幀;
- %x8:表示連接斷開;
- %x8:表示這是一個(gè)ping操作;
- %xA:表示這是一個(gè)pong操作;
- %xB-F:保留的操作代碼,用于后續(xù)定義的控制幀。
- Mask: 1個(gè)比特
- 表示是否要對(duì)數(shù)據(jù)載荷進(jìn)行掩碼操作。從客戶端向服務(wù)端發(fā)送數(shù)據(jù)時(shí),需要對(duì)數(shù)據(jù)進(jìn)行掩碼操作;從服務(wù)端向客戶端發(fā)送數(shù)據(jù)時(shí),不需要對(duì)數(shù)據(jù)進(jìn)行掩碼操作。
- 如果服務(wù)端接收到的數(shù)據(jù)沒有進(jìn)行過掩碼操作,服務(wù)端需要斷開連接。
- 如果Mask是1,那么在Masking-key中會(huì)定義一個(gè)掩碼鍵(masking key),并用這個(gè)掩碼鍵來對(duì)數(shù)據(jù)載荷進(jìn)行反掩碼。所有客戶端發(fā)送到服務(wù)端的數(shù)據(jù)幀,Mask都是1。
- Payload length:數(shù)據(jù)載荷的長(zhǎng)度,單位是字節(jié)。為7位,或7+16位,或1+64位
- 假設(shè)數(shù)Payload length === x,如果:
- x為0~126:數(shù)據(jù)的長(zhǎng)度為x字節(jié);
- x為126:后續(xù)2個(gè)字節(jié)代表一個(gè)16位的無符號(hào)整數(shù),該無符號(hào)整數(shù)的值為數(shù)據(jù)的長(zhǎng)度;
- x為127:后續(xù)8個(gè)字節(jié)代表一個(gè)64位的無符號(hào)整數(shù)(最高位為0),該無符號(hào)整數(shù)的值為數(shù)據(jù)的長(zhǎng)度。
此外,如果payload length占用了多個(gè)字節(jié)的話,payload length的二進(jìn)制表達(dá)采用網(wǎng)絡(luò)序(big endian,重要的位在前)
- Masking-key:0或4字節(jié)(32位)
- 所有從客戶端傳送到服務(wù)端的數(shù)據(jù)幀,數(shù)據(jù)載荷都進(jìn)行了掩碼操作,Mask為1,且攜帶了4字節(jié)的Masking-key。如果Mask為0,則沒有Masking-key。
- 備注:載荷數(shù)據(jù)的長(zhǎng)度,不包括mask key的長(zhǎng)度。
- Payload data:(x+y) 字節(jié)
- 載荷數(shù)據(jù):
- 包括了擴(kuò)展數(shù)據(jù)、應(yīng)用數(shù)據(jù)。其中,擴(kuò)展數(shù)據(jù)x字節(jié),應(yīng)用數(shù)據(jù)y字節(jié);
- 擴(kuò)展數(shù)據(jù):
- 如果沒有協(xié)商使用擴(kuò)展的話,擴(kuò)展數(shù)據(jù)數(shù)據(jù)為0字節(jié)。所有的擴(kuò)展都必須聲明擴(kuò)展數(shù)據(jù)的長(zhǎng)度,或者可以如何計(jì)算出擴(kuò)展數(shù)據(jù)的長(zhǎng)度。此外,擴(kuò)展如何使用必須在握手階段就協(xié)商好。如果擴(kuò)展數(shù)據(jù)存在,那么載荷數(shù)據(jù)長(zhǎng)度必須將擴(kuò)展數(shù)據(jù)的長(zhǎng)度包含在內(nèi);
- 應(yīng)用數(shù)據(jù):
- 任意的應(yīng)用數(shù)據(jù),在擴(kuò)展數(shù)據(jù)之后(如果存在擴(kuò)展數(shù)據(jù)),占據(jù)了數(shù)據(jù)幀剩余的位置。載荷數(shù)據(jù)長(zhǎng)度 減去 擴(kuò)展數(shù)據(jù)長(zhǎng)度,就得到應(yīng)用數(shù)據(jù)的長(zhǎng)度。
5.3 掩碼算法
- 掩碼鍵(Masking-key)是由客戶端挑選出來的32位的隨機(jī)數(shù)。掩碼操作不會(huì)影響數(shù)據(jù)載荷的長(zhǎng)度。
掩碼、反掩碼操作都采用如下算法。
首先,假設(shè):
original-octet-i:為原始數(shù)據(jù)的第i字節(jié)。
transformed-octet-i:為轉(zhuǎn)換后的數(shù)據(jù)的第i字節(jié)。
j:為i mod 4的結(jié)果。
masking-key-octet-j:為mask key第j字節(jié)。
算法描述為:
original-octet-i 與 masking-key-octet-j 異或后,得到 transformed-octet-i。
即:j = i MOD 4
transformed-octet-i = original-octet-i XOR masking-key-octet-j
6 數(shù)據(jù)傳遞
- 一旦WebSocket客戶端、服務(wù)端建立連接后,后續(xù)的操作都是基于數(shù)據(jù)幀的傳遞。WebSocket根據(jù)opcode來區(qū)分操作的類型。比如0x8表示斷開連接,0x0-0x2表示數(shù)據(jù)交互。
6.1 數(shù)據(jù)分片
- WebSocket的每條消息可能被切分成多個(gè)數(shù)據(jù)幀。當(dāng)WebSocket的接收方收到一個(gè)數(shù)據(jù)幀時(shí),會(huì)根據(jù)FIN的值來判斷,是否已經(jīng)收到消息的最后一個(gè)數(shù)據(jù)幀。
- FIN=1表示當(dāng)前數(shù)據(jù)幀為消息的最后一個(gè)數(shù)據(jù)幀,此時(shí)接收方已經(jīng)收到完整的消息,可以對(duì)消息進(jìn)行處理。FIN=0,則接收方還需要繼續(xù)監(jiān)聽接收其余的數(shù)據(jù)幀。
- 此外,opcode在數(shù)據(jù)交換的場(chǎng)景下,表示的是數(shù)據(jù)的類型。0x01表示文本,0x02表示二進(jìn)制。而0x00比較特殊,表示延續(xù)幀(continuation frame),顧名思義,就是完整消息對(duì)應(yīng)的數(shù)據(jù)幀還沒接收完。
6.2 數(shù)據(jù)分片例子
客戶端向服務(wù)端兩次發(fā)送消息,服務(wù)端收到消息后回應(yīng)客戶端,這里主要看客戶端往服務(wù)端發(fā)送的消息。
第一條消息:
FIN=1, 表示是當(dāng)前消息的最后一個(gè)數(shù)據(jù)幀。服務(wù)端收到當(dāng)前數(shù)據(jù)幀后,可以處理消息。opcode=0x1,表示客戶端發(fā)送的是文本類型。
第二條消息:
1)FIN=0,opcode=0x1,表示發(fā)送的是文本類型,且消息還沒發(fā)送完成,還有后續(xù)的數(shù)據(jù)幀;
2)FIN=0,opcode=0x0,表示消息還沒發(fā)送完成,還有后續(xù)的數(shù)據(jù)幀,當(dāng)前的數(shù)據(jù)幀需要接在上一條數(shù)據(jù)幀之后;
3)FIN=1,opcode=0x0,表示消息已經(jīng)發(fā)送完成,沒有后續(xù)的數(shù)據(jù)幀,當(dāng)前的數(shù)據(jù)幀需要接在上一條數(shù)據(jù)幀之后。服務(wù)端可以將關(guān)聯(lián)的數(shù)據(jù)幀組裝成完整的消息。
Client: FIN=1, opcode=0x1, msg="hello"
Server: (process complete message immediately) Hi.
Client: FIN=0, opcode=0x1, msg="and a"
Server: (listening, new message containing text started)
Client: FIN=0, opcode=0x0, msg="happy new"
Server: (listening, payload concatenated to previous message)
Client: FIN=1, opcode=0x0, msg="year!"
Server: (process complete message) Happy new year to you too!
7 連接保持+心跳
- WebSocket為了保持客戶端、服務(wù)端的實(shí)時(shí)雙向通信,需要確??蛻舳?、服務(wù)端之間的TCP通道保持連接沒有斷開。然而,對(duì)于長(zhǎng)時(shí)間沒有數(shù)據(jù)往來的連接,如果依舊長(zhǎng)時(shí)間保持著,可能會(huì)浪費(fèi)包括的連接資源。
- 但不排除有些場(chǎng)景,客戶端、服務(wù)端雖然長(zhǎng)時(shí)間沒有數(shù)據(jù)往來,但仍需要保持連接。
- 這個(gè)時(shí)候,可以采用心跳來實(shí)現(xiàn):
- 發(fā)送方->接收方:ping
- 接收方->發(fā)送方:pong
- ping、pong的操作,對(duì)應(yīng)的是WebSocket的兩個(gè)控制幀,opcode分別是0x9、0xA。
8 Sec-WebSocket-Key/Accept的作用
Sec-WebSocket-Key/Sec-WebSocket-Accept在主要作用在于提供基礎(chǔ)的防護(hù),減少惡意連接、意外連接。
- 作用大致歸納如下:
- 1)避免服務(wù)端收到非法的websocket連接(比如http客戶端不小心請(qǐng)求連接websocket服務(wù),此時(shí)服務(wù)端可以直接拒絕連接);
- 2)確保服務(wù)端理解websocket連接。因?yàn)閣s握手階段采用的是http協(xié)議,因此可能ws連接是被一個(gè)http服務(wù)器處理并返回的,此時(shí)客戶端可以通過Sec-WebSocket-Key來確保服務(wù)端認(rèn)識(shí)ws協(xié)議。(并非百分百保險(xiǎn),比如總是存在那么些無聊的http服務(wù)器,光處理Sec-WebSocket-Key,但并沒有實(shí)現(xiàn)ws協(xié)議。。。);
- 3)用瀏覽器里發(fā)起ajax請(qǐng)求,設(shè)置header時(shí),Sec-WebSocket-Key以及其他相關(guān)的header是被禁止的。這樣可以避免客戶端發(fā)送ajax請(qǐng)求時(shí),意外請(qǐng)求協(xié)議升級(jí)(websocket upgrade);
- 4)可以防止反向代理(不理解ws協(xié)議)返回錯(cuò)誤的數(shù)據(jù)。比如反向代理前后收到兩次ws連接的升級(jí)請(qǐng)求,反向代理把第一次請(qǐng)求的返回給cache住,然后第二次請(qǐng)求到來時(shí)直接把cache住的請(qǐng)求給返回(無意義的返回);
- 5)Sec-WebSocket-Key主要目的并不是確保數(shù)據(jù)的安全性,因?yàn)镾ec-WebSocket-Key、Sec-WebSocket-Accept的轉(zhuǎn)換計(jì)算公式是公開的,而且非常簡(jiǎn)單,最主要的作用是預(yù)防一些常見的意外情況(非故意的)。
強(qiáng)調(diào):Sec-WebSocket-Key/Sec-WebSocket-Accept 的換算,只能帶來基本的保障,但連接是否安全、數(shù)據(jù)是否安全、客戶端/服務(wù)端是否合法的 ws客戶端、ws服務(wù)端,其實(shí)并沒有實(shí)際性的保證。
9 數(shù)據(jù)掩碼的作用
- WebSocket協(xié)議中,數(shù)據(jù)掩碼的作用是增強(qiáng)協(xié)議的安全性。但數(shù)據(jù)掩碼并不是為了保護(hù)數(shù)據(jù)本身,因?yàn)樗惴ū旧硎枪_的,運(yùn)算也不復(fù)雜。除了加密通道本身,似乎沒有太多有效的保護(hù)通信安全的辦法。
- 那么為什么還要引入掩碼計(jì)算呢,除了增加計(jì)算機(jī)器的運(yùn)算量外似乎并沒有太多的收益(這也是不少同學(xué)疑惑的點(diǎn))。
- 答案還是兩個(gè)字:安全。但并不是為了防止數(shù)據(jù)泄密,而是為了防止早期版本的協(xié)議中存在的代理緩存污染攻擊(proxy cache poisoning attacks)等問題。
參考
http://www.itdecent.cn/p/9c09c9a75e9c
http://www.itdecent.cn/p/867274a5e054
http://www.itdecent.cn/p/fc09b0899141