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

Python WebSocket服务端报错unpack requires a buffer of 1 bytes如何解决

问题解决方法

核心错误原因

  • 第一,WebSocket负载长度解析规则不符合协议规范,struct格式符使用错误
    WebSocket RFC6455规定的负载长度编码规则:

    当首字节掩码后的长度值为126时,后续2字节为大端序的16位无符号整数,作为实际负载长度
    当首字节掩码后的长度值为127时,后续8字节为大端序的64位无符号整数,作为实际负载长度
    你当前代码用struct.unpack('B', data)解析,B对应单字节无符号整数,传入2字节/8字节的缓冲区自然会触发长度不匹配的错误,127分支的+=写法也是完全错误的逻辑。

  • 第二,直接调用socket.recv(n)不保证返回恰好n字节数据,TCP是流协议,单次recv可能返回小于请求长度的字节,若未做补收逻辑就直接解析,同样会触发缓冲区长度不足的错误。

修复方案

首先实现一个确保收满指定字节的辅助方法:

def recv_full(self, n):
    data = b''
    while len(data) < n:
        chunk = self.conn.recv(n - len(data))
        if not chunk:
            # 连接异常断开,可根据业务需求调整异常处理逻辑
            self.close_handshake(1006)
    return data

然后修正parse_frame方法的长度解析逻辑:

import struct

def parse_frame(self):
    # 收满2字节基础帧头
    data = self.recv_full(2)

    FIN = (data[0] >> 7) & 1
    RSV1 = (data[0] >> 6) & 1
    RSV2 = (data[0] >> 5) & 1
    RSV3 = (data[0] >> 4) & 1

    OPCODE = data[0] & 0xf
    MASK = (data[1] >> 7) & 1

    if not MASK:
       self.close_handshake(1002)
       
    PAYLOAD_LENGTH = data[1] & 0x7f
    if PAYLOAD_LENGTH == 126:
        # 解析2字节大端序16位无符号整数作为实际长度
        len_data = self.recv_full(2)
        PAYLOAD_LENGTH = struct.unpack('!H', len_data)[0]
    elif PAYLOAD_LENGTH == 127:
        # 解析8字节大端序64位无符号整数作为实际长度
        len_data = self.recv_full(8)
        PAYLOAD_LENGTH = struct.unpack('!Q', len_data)[0]

    MASKING_KEY = self.recv_full(4)
    PAYLOAD_DATA = self.recv_full(PAYLOAD_LENGTH)
    PAYLOAD_DATA = self.unmask(PAYLOAD_DATA, MASKING_KEY)

    return OPCODE, PAYLOAD_DATA

关键修正点说明

  • struct.unpack的格式符!H代表大端序16位无符号短整数,!Q代表大端序64位无符号长整数,完全匹配WebSocket协议的长度编码规则
  • 新增的recv_full方法循环接收数据直到凑齐指定长度,规避TCP流协议单次recv数据不足的问题
  • 移除了127分支错误的+=运算逻辑,直接使用解析出的64位整数作为实际负载长度

内容的提问来源于stack exchange,提问作者user15832679

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:45:06