日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

公司項(xiàng)目使用WebSocket作為主要的請求方式,知其然也要知其所以然,會(huì)用也需要知道它的基本原理,所以寫此文章分享下自己的淺見,文章主要包括以下內(nèi)容:

  • WebSocket是什么
  • WebSocket和Socket區(qū)別
  • 建立連接
  • 數(shù)據(jù)幀格式
  • 發(fā)送數(shù)據(jù)

聊天Demo代碼: github.com/madaoCN/Web… 包含tornado寫的 Server 和 Client 腳本 和 簡單ws使用實(shí)例的IOS代碼

WebSocket是什么

WebSocket是一種在單個(gè) TCP 連接上進(jìn)行 全雙工 通信的協(xié)議,WebSocket使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡單,允許服務(wù)端主動(dòng)向客戶端推送數(shù)據(jù)。在WebSocket API中,瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸。WebSocket協(xié)議在2011年由 IETF 標(biāo)準(zhǔn)化為 RFC 6455

1. 優(yōu)勢

  • 全雙工,服務(wù)器可以主動(dòng)推送數(shù)據(jù)給客戶端,持久連接,實(shí)時(shí)性強(qiáng)
  • 省流量,協(xié)議控制的數(shù)據(jù)包頭部較小,只需要進(jìn)行一次完整的http握手,后續(xù)升級為WebSocket進(jìn)行通信,而HTTP的header一般有幾十字節(jié),而且每次通信都需要攜帶完整的頭部
  • 不僅可以發(fā)送文本,也可以發(fā)送二進(jìn)制,對二進(jìn)制數(shù)據(jù)比較友好

WebSocket和Socket聯(lián)系

Socket其實(shí)并不是一個(gè)協(xié)議,而是為了方便使用TCP或UDP而抽象出來的一層,是位于應(yīng)用層和傳輸控制層之間的一組接口, 而WebSocket和Http一樣是屬于應(yīng)用層協(xié)議。

WebSocket 協(xié)議初探

 

當(dāng)兩臺(tái)主機(jī)通信時(shí),必須通過Socket連接,Socket則利用TCP/IP協(xié)議建立TCP連接。

建立連接

Websocket 握手過程復(fù)用了HTTP協(xié)議的信道,然后對服務(wù)進(jìn)行升級,后續(xù)就使用Websocket協(xié)議進(jìn)行通信,所以只需要一次 HTTP 握手,服務(wù)端就能一直與客戶端保持通信,直到關(guān)閉連接。

一、升級請求

GET / HTTP/1.1
Host: 192.168.1.250:6767
Sec-WebSocket-Version: 13
Upgrade: websocket
Sec-WebSocket-Key: cNtBvwgrxXtqDppb/0mcMw==
Connection: Upgrade
Origin: http://192.168.1.250:6767

與HTTP報(bào)文不太一樣的主要是 Connection: Upgrade : 標(biāo)識(shí)要升級協(xié)議 Upgrade: websocket : 升級到 Websocket 協(xié)議 Sec-WebSocket-Version: 13 : 標(biāo)明WebSocket協(xié)議的版本號 Sec-WebSocket-Key: cNtBvwgrxXtqDppb/0mcMw== 隨機(jī)生成的 ,與服務(wù)端響應(yīng) Sec-WebSocket-Accept 字段對應(yīng),提供基本的防護(hù),防止惡意或者無意的連接,

二、服務(wù)端響應(yīng)報(bào)文

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Sec-Websocket-Accept: hutW70GFRNI1vI45roqiU0Lu33A=
Server: TornadoServer/5.0.2
Connection: Upgrade

Sec-Websocket-Accept : 是根據(jù)客戶端 Sec-WebSocket-Key 計(jì)算而來的

計(jì)算方法為:

258EAFA5-E914-47DA-95CA-C5AB0DC85B11

簡單的Python代碼驗(yàn)證

#coding=utf8
import hashlib
import base64

if __name__ == "__main__":
    sec_key = "cNtBvwgrxXtqDppb/0mcMw=="
    static_key = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
    contact_key = sec_key + static_key

    sha1_rt = hashlib.sha1(contact_key).digest()
    print sec_key
    print base64.encodestring(sha1_rt)
WebSocket 協(xié)議初探

 

三、抓包驗(yàn)證

使用WireShark對WebSocket連接過程抓包

WebSocket 協(xié)議初探

 

很直觀的可以看到 HTTP三次握手 -> 升級協(xié)議 -> 使用WebSocket通信 的過程

WebSocket 協(xié)議初探

 


WebSocket 協(xié)議初探

 

Websocket升級協(xié)議報(bào)文也與上文一致,大家可以自行運(yùn)行Demo代碼,然后使用WireShark進(jìn)行抓包驗(yàn)證請求過程和報(bào)文

數(shù)據(jù)幀格式

如果我們數(shù)據(jù)幀格式都不清楚的話,更遑論說了解WebSocket協(xié)議了

數(shù)據(jù)幀概覽

數(shù)據(jù)幀(frame)是WebSocket通信的基本單位,一個(gè)消息由一個(gè)或者多個(gè)幀組成,內(nèi)容包括標(biāo)志位,操作碼,掩碼,數(shù)據(jù)長度等

0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-------+-+-------------+-------------------------------+
 |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
 |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
 |N|V|V|V|       |S|             |   (if payload len==126/127)   |
 | |1|2|3|       |K|             |                               |
 +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
 |     Extended payload length continued, if payload len == 127  |
 + - - - - - - - - - - - - - - - +-------------------------------+
 |                               |Masking-key, if MASK set to 1  |
 +-------------------------------+-------------------------------+
 | Masking-key (continued)       |          Payload Data         |
 +-------------------------------- - - - - - - - - - - - - - - - +
 :                     Payload Data continued ...                :
 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
 |                     Payload Data continued ...                |
 +---------------------------------------------------------------+

引用自 RFC 6455 - Base Framing Protocol 這個(gè)一章節(jié)

數(shù)據(jù)幀格式

  • FIN1bit 表明是消息的最后一個(gè)數(shù)據(jù)幀,數(shù)據(jù)幀有可能是第一個(gè),同時(shí)也是最后一個(gè)
  • RSV1, RSV2, RSV3每個(gè)1 bit 一般都設(shè)置為0,如果客戶端和服務(wù)端采用了拓展,那么就可以為非0值,非0值的含義由拓展來決定,如果收到了非0的值,而且未采用拓展協(xié)商,那么接收終端就應(yīng)該斷開WebSocket連接
  • 操作碼4個(gè)bit 決定了后續(xù)的載荷數(shù)據(jù)(Payload data)的解析方式,如果收到了未知的操作碼,那么接收終端就應(yīng)該斷開WebSocket連接,具體的操作碼如下:
*  %x0  :  表明了這個(gè)一個(gè)持續(xù)幀(continuation frame),當(dāng)操作碼為0時(shí),說明使用了數(shù)據(jù)分片,該幀為數(shù)據(jù)分片中的一幀

*  %x1  :表明了這是一個(gè)文本幀(text frame)

*  %x2  :表明了這是一個(gè)二進(jìn)制幀(binary frame)

*  %x3-7  :保留操作碼,用于后續(xù)定義的非控制幀further non-control frames)

*  %x8  :表明了這是一個(gè)關(guān)閉操作碼

*  %x9  :表明了這是一個(gè)ping操作碼

*  %xA  :表明了這是一個(gè)pong操作碼

*  %xB-F :保留操作碼, 用于后續(xù)定義的控制幀( further control frames)
復(fù)制代碼
  • Mask 4個(gè)bit

表明是否要對載荷數(shù)據(jù)(Payload data)進(jìn)行掩碼操作,如果被置為1,那么 Masking-key 會(huì)定義一個(gè) 32位,4個(gè)字節(jié)的值,用于對載荷數(shù)據(jù)(Payload data)的反掩碼操作,具體掩碼的算法在后續(xù)內(nèi)容中進(jìn)行說明

值得注意的是,只有在客戶端向服務(wù)端發(fā)送數(shù)據(jù)時(shí),Mask才為1,而服務(wù)端向客戶端發(fā)送數(shù)據(jù)時(shí)不需要進(jìn)行掩碼操作

  • Masking-key 0 或者4個(gè)bit

客戶端向服務(wù)端發(fā)送的數(shù)據(jù)都進(jìn)行了掩碼操作,客戶端必須為發(fā)送的每一個(gè)frame選擇新的掩碼 (隨機(jī)生成),要求是這個(gè)掩碼無法被提供數(shù)據(jù)的終端應(yīng)用(即客戶端)預(yù)測 備注:掩碼長度不計(jì)入載荷數(shù)據(jù)(Payload data)的長度

  • Payload length 7 bits 或 7+16 bits 或 7+64 bits 長度為0 - 125 : 那么它就是載荷(playload)的長度 長度為126 : 那么接下來的2個(gè)字節(jié)(16位無符號整型)就是載荷(playload)的長度 長度為127 : 那么接下來的8個(gè)字節(jié)(64位無符號整型)就是載荷(playload)的長度

另外,Payload length采用了網(wǎng)絡(luò)字節(jié)序,也就是大端(big endian數(shù)據(jù)的高字節(jié)保存在內(nèi)存的低地址中),大小端具體詳情請看百度百科 大小端模式

  • Payload data(x+y) 字節(jié) 載荷數(shù)據(jù)包括了應(yīng)用數(shù)據(jù)(x)和拓展數(shù)據(jù)(y) 應(yīng)用數(shù)據(jù) y 字節(jié): 如果存在拓展數(shù)據(jù)的話,占據(jù)了拓展數(shù)據(jù)之后的幀位置 拓展數(shù)據(jù) x字節(jié): 除非客戶端和服務(wù)端進(jìn)行了協(xié)商,那么拓展數(shù)據(jù)應(yīng)為0,否則拓展數(shù)據(jù)應(yīng)當(dāng)在握手過程中明確定義其長度,或者協(xié)商如何進(jìn)行長度計(jì)算(如果存在拓展數(shù)據(jù),那么它的長度應(yīng)當(dāng)也計(jì)入載荷長度中)
  • 掩碼的算法
/**
original-octet-i為原始數(shù)據(jù)的第i字節(jié)
masking-key-octet-j為masking-key的第j個(gè)字節(jié)
transformed-octet-i為掩碼計(jì)算后的第i個(gè)字節(jié)
*/
Octet i of the transformed data ("transformed-octet-i") is the XOR of
octet i of the original data ("original-octet-i") with octet at index
i modulo 4 of the masking key ("masking-key-octet-j"):

 j                   = i MOD 4
 transformed-octet-i = original-octet-i XOR masking-key-octet-j

摘抄自 RFC : Client-to-Server Masking

也就是將原始數(shù)據(jù)和masking-key做異或操作(異或的位數(shù) j = i mode 4),獲得的就是轉(zhuǎn)換后的結(jié)果

發(fā)送數(shù)據(jù)

WebSocket根據(jù) opcode 操作碼來區(qū)分操作類型, %x0 %x1 %x2 代表了數(shù)據(jù)交互幀

  • %x0 : 表明了這個(gè)一個(gè)持續(xù)幀(continuation frame),當(dāng)操作碼為0時(shí),說明使用了數(shù)據(jù)分片,該幀為數(shù)據(jù)分片中的一幀
  • %x1 :表明了這是一個(gè)文本幀(text frame)
  • %x2 :表明了這是一個(gè)二進(jìn)制幀(binary frame

特別的操作碼 %x0 代表使用了數(shù)據(jù)分片,消息可能被切分成多個(gè)數(shù)據(jù)幀,筆者發(fā)現(xiàn) tornado 和 SocketRocket 并沒有實(shí)現(xiàn)數(shù)據(jù)分片,這里就暫不深入討論,詳情請參考 RFC: Fragmentation

存活心跳ping 和 pong

一旦建立與服務(wù)器的連接,客戶端和服務(wù)端都可以發(fā)起一個(gè)ping請求,當(dāng)接收到一個(gè)ping請求,那么接收端必須要盡快回復(fù)pong請求,通過這種方式,來確認(rèn)對方是否存活,確保客戶端、服務(wù)端之間的TCP通道保持連接沒有斷開

ping, pong操作碼分別為 %x9 %xA

斷開連接

客戶端和服務(wù)端都可以通過發(fā)送帶有特殊控制序列 %x8 的數(shù)據(jù)幀來發(fā)起斷開連接,一旦某一端收到該幀,需要也響應(yīng)一個(gè)斷開幀,之后主動(dòng)斷開的那端便可以關(guān)閉連接了,之前提到過Websocket 握手過程復(fù)用了HTTP協(xié)議的信道,那么很自然的,斷開連接期間也經(jīng)歷了四次揮手的過程

Sec-WebSocket-Key/Accept的作用

Sec-WebSocket-Key/Sec-WebSocket-Accept 的算法都是公開的,而且也不復(fù)雜,僅僅是提供一些基礎(chǔ)防護(hù),防止一些意外鏈接,和惡意鏈接

WebSocket協(xié)議:5分鐘從入門到精通 ]( www.cnblogs.com/chyingp/p/w… )中已經(jīng)寫得很詳細(xì),這邊就不做詳細(xì)探究

數(shù)據(jù)掩碼的作用

隨著websocket協(xié)議被開發(fā)出來,一項(xiàng)針對代理服務(wù)器的攻擊(污染那些廣泛部署的緩存代理服務(wù)器)實(shí)驗(yàn)也開始進(jìn)行。 一般形式的攻擊是跟被攻擊者控制的服務(wù)器建立連接,并構(gòu)造一個(gè)類似WebSocket握手一樣的UPGRADE請求,隨后通過UPGRADE建立的連接發(fā)送看起來就像GET請求的frame去獲取一個(gè)已知資源(在攻擊場景中可能是一個(gè)點(diǎn)擊跟蹤腳本或廣告服務(wù)網(wǎng)絡(luò)中的資源) 之后遠(yuǎn)程服務(wù)器會(huì)返回某些東西,就像對于這個(gè)偽造GET請求的響應(yīng),并且這個(gè)響應(yīng)會(huì)被很多廣泛部署的網(wǎng)絡(luò)中間設(shè)備緩存,從而達(dá)到了污染緩存服務(wù)器的目的。對于這個(gè)攻擊的產(chǎn)生的效應(yīng),可能一個(gè)用戶被誘導(dǎo)訪問受攻擊者操控的服務(wù)器,攻擊者就有可能污染這個(gè)用戶以及其他共享相同緩存服務(wù)用戶的緩存服務(wù)器,并跨域執(zhí)行惡意腳本,破壞web安全模型

總結(jié)一下,掩碼的作用很重要兩點(diǎn)就是 防止攻擊者獲知網(wǎng)絡(luò)鏈路中傳輸?shù)脑紨?shù)據(jù) 和 避免緩存

分享到:
標(biāo)簽:協(xié)議 WebSocket
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定