websocket協議詳解及報文分析


       Webscoket是Web瀏覽器和服務器之間的一種全雙工通信協議。一旦Web客戶端與服務器建立起連接,之后的全部數據通信都通過這個連接進行。通信過程中,可互相發送JSON、XML、HTML或圖片等任意格式的數據。

  WS(WebSocket)與HTTP協議比較:

都是基於TCP的應用層協議;
都使用Request/Response模型進行連接的建立;
在連接的建立過程中對錯誤的處理方式相同,在這個階段WS可能返回和HTTP相同的返回碼;
都可以在網絡中傳輸數據。

  不同之處

WS使用HTTP來建立連接,但是定義了一系列新的header域,這些域在HTTP中並不會使用;
WS的連接不能通過中間人來轉發,它必須是一個直接連接;
WS連接建立之后,通信雙方都可以在任何時刻向另一方發送數據;
WS連接建立之后,數據的傳輸使用幀來傳遞,不再需要Request消息;
WS的數據幀有序。

  WS整個通信過程如下圖所示:

 

 

   websocket是基於TCP的一個應用協議,與HTTP協議的關聯之處在於websocket的握手數據被HTTP服務器當作HTTP包來處理,主要通過Update request HTTP包建立起連接,之后的通信全部使用websocket自己的協議。

  **請求:**TCP連接建立后,客戶端發送websocket的握手請求,請求報文頭部如下:

GET /uin=xxxxxxxx&app=xxxxxxxxx&token=XXXXXXXXXXXX HTTP/1.1
Host: server.example.cn:443
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36
Upgrade: websocket
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: user_id=XXXXX
Sec-WebSocket-Key: 1/2hTi/+eNURiekpNI4k5Q==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: binary, base64

  第一行為為請求的方法,類型必須為GET,協議版本號必須大於1.1

  Upgrade字段必須包含,值為websocket
  Connection字段必須包含,值為Upgrade
  Sec-WebSocket-Key字段必須包含 ,記錄着握手過程中必不可少的鍵值。
  Sec-WebSocket-Protocol字段必須包含 ,記錄着使用的子協議
  Origin(請求頭):Origin用來指明請求的來源,Origin頭部主要用於保護Websocket服務器免受非授權的跨域腳本調用Websocket API的請求。也就是不想沒被授權的跨域訪問與服務器建立連接,服務器可以通過這個字段來判斷來源的域並有選擇的拒絕。
  **響應:**服務器接收到請求后,返回狀態碼為101 Switching Protocols 的響應。

HTTP/1.1 101 Switching Protocols
Server: WebSockify Python/2.6.6
Date: Wed, 27 May 2020 03:03:21 GMT
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: hXXXXXXXXXXXXXXxGmM=
Sec-WebSocket-Protocol: binary

  Sec-WebSocket-Accept字段是由握手請求中的Sec-WebSocket-Key字段生層的。

  握手成功后,通信不再使用HTTP協議,而采用WebSocket獨立的數據幀。如下圖所示,為協議幀格式:

  

FIN,指明Frame是否是一個Message里最后Frame(之前說過一個Message可能又多個Frame組成);1bit,是否為信息的最后一幀
RSV1-3,默認是0 (必須是0),除非有擴展定義了非零值的意義。
Opcode,這個比較重要,有如下取值是被協議定義的
                0x00 denotes a continuation frame
                0x01 表示一個text frame
                0x02 表示一個binary frame
                0x03 ~~ 0x07 are reserved for further non-control frames,為將來的非控制消息片段保留測操作碼
                0x08 表示連接關閉
                0x09 表示 ping (心跳檢測相關)
                0x0a 表示 pong (心跳檢測相關)
                0x0b ~~ 0x0f are reserved for further control frames,為將來的控制消息片段保留的操作碼
Mask,這個是指明“payload data”是否被計算掩碼。這個和后面的Masking-key有關,如果設置為1,掩碼鍵必須放在masking-key區域,客戶端發送給服務端的所有消息,此位的值都是1;
Payload len,數據的長度,
Masking-key,0或者4bit,只有當MASK設置為1時才有效。,給一個Websocket中掩碼的意義
Payload data,幀真正要發送的數據,可以是任意長度,但盡管理論上幀的大小沒有限制,但發送的數據不能太大,否則會導致無法高效利用網絡帶寬,正如上面所說Websocket提供分片。
Extension data:擴展數據,如果客戶端和服務端沒有特殊的約定,那么擴展數據長度始終為0
Application data:應用數據,

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM