Websocket笔记

Websocket笔记

文章目录

标准

RFC6455 https://datatracker.ietf.org/doc/html/rfc6455

握手请求

REQ

http 复制代码
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

字段含义

GET /chat HTTP/1.1

GET: HTTP 请求方法,用于获取资源。在 WebSocket 握手中,这个方法用于发起连接请求。

/chat: 请求的路径。

HTTP/1.1: 使用的 HTTP 版本,通常是 1.1。

Host: server.example.com

指定请求的目标服务器主机名和端口号。这个字段是 HTTP/1.1 的标准要求,表示目标服务器的域名。

Upgrade: websocket

表示客户端希望将当前的 HTTP 连接升级为 WebSocket 连接。

Connection: Upgrade

表示连接应该升级。这个字段配合 Upgrade 字段使用。

Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

一个 16 字节的随机 Base64 编码的字符串,由客户端生成。用于安全验证,防止不正当的 WebSocket 连接。

Sec-WebSocket-Version: 13

指定 WebSocket 协议的版本。当前规范中,13 是唯一合法值(定义在 RFC 6455 中)。

Origin: http://example.com

指示 WebSocket 请求的来源。服务器可以使用这个字段来检查请求是否来自允许的来源,以防止跨站点 WebSocket 攻击(CSWSH)。这个字段在浏览器环境中是强制性的。

Sec-WebSocket-Protocol: chat, superchat

可选字段,表示客户端支持的子协议。子协议是在 WebSocket 连接上进行特定类型的通信协议,比如聊天、流媒体等。服务器会在响应中选择一个协议,或者忽略这个字段。

Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

可选字段,用于指定 WebSocket 扩展。扩展功能可以优化或增强 WebSocket 的通信能力,例如压缩消息等。服务器可以在响应中确认支持的扩展。

RES

http 复制代码
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

服务器响应字段含义

HTTP/1.1 101 Switching Protocols

表示服务器接受了协议升级请求,并切换到 WebSocket 协议。

Upgrade: websocket

表示服务器同意升级到 WebSocket 协议。

Connection: Upgrade

表示连接已升级。

Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

服务器基于客户端发送的 Sec-WebSocket-Key 计算出的 Base64 编码字符串,用于确认握手的有效性。

Sec-WebSocket-Protocol: chat

如果客户端请求了多个子协议,服务器会在此字段中返回所选的协议。

Sec-WebSocket-Extensions: permessage-deflate

返回服务器支持的扩展。

数据帧格式

text 复制代码
      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 ...                |
     +---------------------------------------------------------------+

格式解析

  1. FIN (1 bit)
    FIN (Final frame):指示该帧是否是消息的最后一帧。
    1 表示这是消息的最后一帧。
    0 表示后面还有更多帧属于同一消息。
  2. RSV1, RSV2, RSV3 (各 1 bit)
    这三个保留位(Reserved bits)通常设置为 0,除非某些扩展定义了这些位的用途。
    如果未使用扩展,服务器和客户端必须忽略这三个位。
  3. Opcode (4 bits)
    操作码:指定帧的类型,定义了该帧携带的负载数据的解释方式。
    常用操作码:
    0x0:连续帧(Continuation frame)
    0x1:文本帧(Text frame)
    0x2:二进制帧(Binary frame)
    0x8:连接关闭帧(Connection close frame)
    0x9:Ping 帧(Ping frame)
    0xA:Pong 帧(Pong frame)
    其他值保留用于未来定义。
  4. MASK (1 bit)
    掩码标志:指示是否对负载数据进行了掩码处理。
    1 表示负载数据已被掩码处理。
    0 表示负载数据未被掩码处理。
    从客户端发送到服务器的帧必须设置掩码标志,服务器到客户端的帧则通常不需要。
  5. Payload length (7 bits, 7+16 bits, or 7+64 bits)
    负载长度:表示负载数据的长度。
    0-125:负载数据的实际长度。
    126:负载长度为 16 位,后面的 16 位字段用于表示长度(最大值为 65535)。
    127:负载长度为 64 位,后面的 64 位字段用于表示长度(最大值为 2^63-1)。
  6. Extended payload length (16 bits or 64 bits)
    扩展负载长度:如果负载长度字段的值为 126 或 127,则此部分用于表示实际的负载数据长度。
    126:16 位(2 字节)扩展负载长度字段。
    127:64 位(8 字节)扩展负载长度字段。
  7. Masking-key (32 bits)
    掩码键:如果掩码标志位为 1,这个字段包含了 4 字节的掩码键。
    客户端发送给服务器的帧必须包含掩码键,服务器会使用该键对数据进行解码。
  8. Payload Data (x+y bits)
    负载数据:实际传输的数据内容。
    如果使用了掩码处理,负载数据必须先通过掩码键解码。
    负载数据的长度由前面的 Payload length 和 Extended payload length 字段确定。
  9. Payload Data Continued
    如果负载数据非常长,它可能会跨越多个帧。
    如果 FIN 位设置为 0,表示后续还有数据帧,它们将与当前帧的负载数据组合形成完整消息。
相关推荐
代码or搬砖17 小时前
Git学习笔记(二)
笔记·git·学习
报错小能手18 小时前
linux学习笔记(26)计算机网络基础
linux·笔记·学习
hbqjzx18 小时前
带条件的排名问题
笔记
默凉18 小时前
cpp http 客户端与服务端 POST请求
网络·网络协议·http
盛满暮色 风止何安18 小时前
防火墙的类别和登录Web的方法
linux·运维·服务器·网络·网络协议·tcp/ip·网络安全
Arlene19 小时前
HTTP 的方法和状态码
网络·网络协议·http
哈乐19 小时前
主流网络协议--助记
网络·网络协议
Miki Makimura20 小时前
UDP可靠性传输指南:从基础机制到KCP协议核心解析
网络·网络协议·学习·udp
少年、潜行21 小时前
IMX6ULL学习笔记_Boot和裸机篇(6)--- IMX6ULL简单SHELL以及SEGGER ES的Printf和字节对齐问题
笔记·学习·imx6ull·字节对齐·printf格式化
取酒鱼食--【余九】1 天前
GRU(门控循环单元) 笔记
笔记·深度学习·gru