zoukankan      html  css  js  c++  java
  • websocket 建立过程以及数据帧分析

    websocket 建立过程

    客户端请求

    • Connection: Upgrade 表示要升级协议
    • Upgrade: websocket 告诉服务器要升级为 websocket 协议
    • Sec-WebSocket-Version: 13 表示 websocket 的版本。如果服务端不支持该版本,需要返回一个Sec-WebSocket-Versionheader,里面包含服务端支持的版本号。
    • Sec-WebSocket-Key:客户端随机生成的一个base64编码,与后面服务端响应头配套,提供基本的防护,防止无意的连接。
    GET /chat HTTP/1.1     
    Host: server.example.com     
    Upgrade: websocket     
    Connection: Upgrade     
    Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==     
    Sec-WebSocket-Protocol: chat, superchat     
    Sec-WebSocket-Version: 13     
    Origin: http://example.com
    
    

    服务器响应

    • 服务器返回 101 状态码,并切换为 WebSocket 协议建立全双工连接
    • Sec-WebSocket-Accept:客户端请求头的 Sec-Websocket-Key 与 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 拼接,通过 SHA1 算摘要,最后转为 base64 字符串返回。

    所谓防止无意的连接是指,http 客户端不小心请求了 websocket 服务。

    HTTP/1.1 101 
    Switching Protocols     
    Upgrade: websocket     
    Connection: Upgrade     
    Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=     
    Sec-WebSocket-Protocol: chat
    

    数据帧分析

    图来自掘金-黄Java-【译】WebSocket协议第五章——数据帧(Data Framing)

          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 ...                |
         +---------------------------------------------------------------+
    
    

    FIN: 1 bit。表示这是消息的最后一个片段。第一个片段也有可能是最后一个片段。

    RSV1,RSV2,RSV3: 每个1 bit。必须设置为0,除非扩展了非0值含义的扩展。如果收到了一个非0值但是没有扩展任何非0值的含义,接收终端必须断开WebSocket连接。

    Opcode: 4 bit。操作码,如果收到一个未知的操作码,接收终端必须断开WebSocket连接。

    • %x0 表示一个持续帧
    • %x1 表示一个文本帧
    • %x2 表示一个二进制帧
    • %x3-7 预留给以后的非控制帧
    • %x8 表示一个连接关闭包
    • %x9 表示一个ping包
    • %xA 表示一个pong包
    • %xB-F 预留给以后的控制帧

    Mask: 1 bit,mask标志位,定义“有效负载数据”是否添加掩码。如果设置为1,那么掩码的键值存在于Masking-Key中。Masking-Key中一般用于解码“有效负载数据”。

    Payload length: 7 bits, 7+16 bits, or 7+64 bits,以字节为单位的“有效负载数据”长度。如果值为0-125,那么就表示负载数据的长度。如果是126,那么接下来的2个bytes解释为16bit的无符号整形作为负载数据的长度。如果是127,那么接下来的8个bytes解释为一个64bit的无符号整形(最高位的bit必须为0)作为负载数据的长度。多字节长度量以网络字节顺序表示(译注:应该是指大端序和小端序)。在所有的示例中,长度值必须使用最小字节数来进行编码,例如:长度为124字节的字符串不可用使用序列126,0,124进行编码。有效负载长度是指“扩展数据”+“应用数据”的长度。“扩展数据”的长度可能为0,那么有效负载长度就是“应用数据”的长度。

    Masking-Key: 0 or 4 bytes,所有从客户端发往服务端的数据帧都已经与一个包含在这一帧中的32 bit的掩码进行过了运算。为什么需要掩码?为了安全,但并不是为了防止数据泄密,而是为了防止早期版本的协议中存在的代理缓存污染攻击(proxy cache poisoning attacks)等问题。

    Payload data:有效负载数据,是指“扩展数据”和“应用数据”。

    Extension data: x bytes:除非协商过扩展,否则“扩展数据”长度为0 bytes。

    Application data: y bytes。任意的“应用数据”,占用“扩展数据”后面的剩余所有字段。“应用数据”的长度等于有效负载长度减去“扩展应用”长度。

    参考

    即时通信网-Web端即时通讯技术盘点

    掘金-黄Java-Websocket 协议 RFC 文档(全中文翻译)

    原来你是这样的 websocket

  • 相关阅读:
    (十)安装YAML
    (十四)日志
    Android自动化测试------monkeyrunner(六)
    Android自动化测试------monkey日志管理(五)
    如何学好一门编程语言
    linux vi hjkl由来
    .net 微服务CICD 好文章
    APPCMD 精心整理 有点赞的吗
    APPCMD 命令合集
    APPCMD 使用手册
  • 原文地址:https://www.cnblogs.com/everlose/p/12779624.html
Copyright © 2011-2022 走看看