You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebSocket帧PAYLOAD_LENGTH为126时EXTENDED_PAYLOAD_LENGTH计算方法

WebSocket负载长度计算(Java实现方案)

结论先行

使用位运算的思路完全正确,是处理WebSocket帧长度解析的标准方案,无需逐位读取,仅按字节读取即可实现。

核心规则说明

引用RFC6455的负载长度定义:

The length of the "Payload data", in bytes: if 0-125, that is the payload length. If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length. If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the most significant bit MUST be 0) are the payload length.
注意两个关键细节:

  • 帧的第二个字节最高位是掩码标识位,计算长度标识时需要取低7位,推荐用b2 & 0x7F实现,比直接减128更稳妥,不会受Java有符号字节的特性影响
  • 扩展长度的字节序为大端序(网络字节序),即先读取的字节为高位,后读取的为低位

双字节扩展长度合并逻辑

当长度标识为126时,第三字节为16位无符号整数的高8位,第四字节为低8位,合并步骤如下:

  1. 用& 0xFF将每个有符号byte转换为对应的无符号int值,避免符号位自动补全导致的计算错误
  2. 将高8位左移8位,放到16位整数的高段位置
  3. 用按位或运算合并高低8位,得到最终的16位无符号负载长度
    对应Java代码如下:
// b3为第三字节,b4为第四字节
int payloadLength = ((b3 & 0xFF) << 8) | (b4 & 0xFF);

完整长度解析示例代码

public long parsePayloadLength(byte[] frameHeader) {
    // frameHeader至少包含前2个字节,标识为126时至少4字节,127时至少10字节
    int payloadLenFlag = frameHeader[1] & 0x7F;
    if (payloadLenFlag <= 125) {
        return payloadLenFlag;
    } else if (payloadLenFlag == 126) {
        return ((frameHeader[2] & 0xFF) << 8) | (frameHeader[3] & 0xFF);
    } else {
        // 127对应8字节扩展长度,用long存储避免溢出
        return ((long)(frameHeader[2] & 0xFF) << 56)
             | ((long)(frameHeader[3] & 0xFF) << 48)
             | ((long)(frameHeader[4] & 0xFF) << 40)
             | ((long)(frameHeader[5] & 0xFF) << 32)
             | ((long)(frameHeader[6] & 0xFF) << 24)
             | ((long)(frameHeader[7] & 0xFF) << 16)
             | ((long)(frameHeader[8] & 0xFF) << 8)
             | (frameHeader[9] & 0xFF);
    }
}

内容的提问来源于stack exchange,提问作者Jason Rich Darmawan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 18:06:03