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

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

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

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

  • WebSocket是什么
  • WebSocket和Socket區別
  • 建立連接
  • 數據幀格式
  • 發送數據

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

WebSocket是什么

WebSocket是一種在單個 TCP 連接上進行 全雙工 通信的協議,WebSocket使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據。在WebSocket API中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,并進行雙向數據傳輸。WebSocket協議在2011年由 IETF 標準化為 RFC 6455

1. 優勢

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

WebSocket和Socket聯系

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

WebSocket 協議初探

 

當兩臺主機通信時,必須通過Socket連接,Socket則利用TCP/IP協議建立TCP連接。

建立連接

Websocket 握手過程復用了HTTP協議的信道,然后對服務進行升級,后續就使用Websocket協議進行通信,所以只需要一次 HTTP 握手,服務端就能一直與客戶端保持通信,直到關閉連接。

一、升級請求

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報文不太一樣的主要是 Connection: Upgrade : 標識要升級協議 Upgrade: websocket : 升級到 Websocket 協議 Sec-WebSocket-Version: 13 : 標明WebSocket協議的版本號 Sec-WebSocket-Key: cNtBvwgrxXtqDppb/0mcMw== 隨機生成的 ,與服務端響應 Sec-WebSocket-Accept 字段對應,提供基本的防護,防止惡意或者無意的連接,

二、服務端響應報文

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

Sec-Websocket-Accept : 是根據客戶端 Sec-WebSocket-Key 計算而來的

計算方法為:

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

簡單的Python代碼驗證

#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 協議初探

 

三、抓包驗證

使用WireShark對WebSocket連接過程抓包

WebSocket 協議初探

 

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

WebSocket 協議初探

 


WebSocket 協議初探

 

Websocket升級協議報文也與上文一致,大家可以自行運行Demo代碼,然后使用WireShark進行抓包驗證請求過程和報文

數據幀格式

如果我們數據幀格式都不清楚的話,更遑論說了解WebSocket協議了

數據幀概覽

數據幀(frame)是WebSocket通信的基本單位,一個消息由一個或者多個幀組成,內容包括標志位,操作碼,掩碼,數據長度等

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 這個一章節

數據幀格式

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

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

*  %x2  :表明了這是一個二進制幀(binary frame)

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

*  %x8  :表明了這是一個關閉操作碼

*  %x9  :表明了這是一個ping操作碼

*  %xA  :表明了這是一個pong操作碼

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

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

值得注意的是,只有在客戶端向服務端發送數據時,Mask才為1,而服務端向客戶端發送數據時不需要進行掩碼操作

  • Masking-key 0 或者4個bit

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

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

另外,Payload length采用了網絡字節序,也就是大端(big endian數據的高字節保存在內存的低地址中),大小端具體詳情請看百度百科 大小端模式

  • Payload data(x+y) 字節 載荷數據包括了應用數據(x)和拓展數據(y) 應用數據 y 字節: 如果存在拓展數據的話,占據了拓展數據之后的幀位置 拓展數據 x字節: 除非客戶端和服務端進行了協商,那么拓展數據應為0,否則拓展數據應當在握手過程中明確定義其長度,或者協商如何進行長度計算(如果存在拓展數據,那么它的長度應當也計入載荷長度中)
  • 掩碼的算法
/**
original-octet-i為原始數據的第i字節
masking-key-octet-j為masking-key的第j個字節
transformed-octet-i為掩碼計算后的第i個字節
*/
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

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

發送數據

WebSocket根據 opcode 操作碼來區分操作類型, %x0 %x1 %x2 代表了數據交互幀

  • %x0 : 表明了這個一個持續幀(continuation frame),當操作碼為0時,說明使用了數據分片,該幀為數據分片中的一幀
  • %x1 :表明了這是一個文本幀(text frame)
  • %x2 :表明了這是一個二進制幀(binary frame

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

存活心跳ping 和 pong

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

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

斷開連接

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

Sec-WebSocket-Key/Accept的作用

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

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

數據掩碼的作用

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

總結一下,掩碼的作用很重要兩點就是 防止攻擊者獲知網絡鏈路中傳輸的原始數據 和 避免緩存

分享到:
標簽:協議 WebSocket
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

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

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定