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,表示后续还有数据帧,它们将与当前帧的负载数据组合形成完整消息。
相关推荐
轩辰~32 分钟前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
oneouto1 小时前
selenium学习笔记(二)
笔记·学习·selenium
sealaugh322 小时前
aws(学习笔记第十九课) 使用ECS和Fargate进行容器开发
笔记·学习·aws
LuH11243 小时前
【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo
论文阅读·笔记
EasyDSS4 小时前
国标GB28181-2022平台EasyGBS:安防监控中P2P的穿透方法
网络协议·php·音视频·p2p
网安墨雨4 小时前
常用网络协议
网络·网络协议
m0_748256785 小时前
WebGIS实战开源项目:智慧机场三维可视化(学习笔记)
笔记·学习·开源
红色的山茶花5 小时前
YOLOv9-0.1部分代码阅读笔记-loss.py
笔记
ZoeLandia6 小时前
WebSocket | 背景 概念 原理 使用 优缺点及适用场景
网络·websocket·网络协议
胡西风_foxww7 小时前
【es6复习笔记】Promise对象详解(12)
javascript·笔记·es6·promise·异步·回调·地狱