WebSocket不直接发送十六进制字符串,需先将如"7E FF 01 02"解析为Uint8Array字节序列,再调用ws.send(uint8array.buffer)发送二进制帧;收端须按binaryType设置并检查event.data instanceof ArrayBuffer来正确解析原始字节。

WebSocket 本身不直接“发送十六进制”,它只传输 String(UTF-8 文本)或 ArrayBuffer/Blob(二进制)。所谓“发十六进制”,本质是把你要的原始字节序列,用十六进制字符串表示 → 再转回二进制 → 再通过 WebSocket 发送。关键在两端对齐:**发端能正确构造字节,收端能按约定解析字节**。
前端 JS 怎么把 "7E FF 01 02" 这种字符串发成二进制帧
浏览器 WebSocket 的 send() 不接受十六进制字符串,必须转成 ArrayBuffer 或 Uint8Array 后再发。
- 先去掉空格、转大写(避免大小写混用导致
parseInt(..., 16)失败) - 每两个字符一组,用
parseInt(hexPair, 16)转成数字,塞进Uint8Array - 最后用
ws.send(uint8array.buffer)发送二进制帧(注意不是 send 字符串!)
示例:
function hexStringToBytes(hexStr) {
const clean = hexStr.replace(/\s/g, '').toUpperCase();
const bytes = new Uint8Array(clean.length / 2);
for (let i = 0; i < clean.length; i += 2) {
bytes[i / 2] = parseInt(clean.substr(i, 2), 16);
}
return bytes;
}
const ws = new WebSocket('ws://localhost:8080');
ws.onopen = () => {
const payload = hexStringToBytes('7E FF 01 02 03');
ws.send(payload.buffer); // ✅ 发 BinaryWebSocketFrame
};
Java 后端(如 Spring WebSocket / Netty)怎么接收并解析十六进制字节
服务端收到的是 BinaryWebSocketFrame(Netty)或 byte[](Spring),不是字符串。别用 new String(bytes) 去打印——会乱码,也破坏原始字节值。
- 直接操作
byte[]数组,按协议定义读取字段(比如头 1 字节是帧起始符0x7E,第 2 字节是命令类型) - 调试时想看十六进制可打印:用
String.format("%02X", b & 0xFF)遍历每个字节 - 若用 Netty,确保 pipeline 中有
WebSocketServerProtocolHandler,且自定义 handler 继承SimpleChannelInboundHandler<BinaryWebSocketFrame>,而不是处理TextWebSocketFrame
常见错误:ws.send("7EFF0102") → 后端收到的是 ASCII 字符 '7','E','F','F'…共 8 个字节,不是你想要的 4 字节 0x7E, 0xFF, 0x01, 0x02。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
PHP / Python 等后端发十六进制数据给前端时要注意什么
它们没有浏览器的 WebSocket API 限制,但需明确发送的是二进制帧,不是文本帧。
- PHP(用 Ratchet 或 Swoole):调用
$conn->send(hex2bin("7EFF01")),不能 send 字符串 "7EFF01" - Python(用 websockets 库):用
await websocket.send(bytes.fromhex("7E FF 01")),bytes.fromhex()自动忽略空格 - 关键点:前端
ws.onmessage中要检查event.data instanceof ArrayBuffer,否则会当成字符串解析失败
如果后端误发了字符串(如 send("7E01FF")),前端收到的是 typeof event.data === 'string',此时 event.data.charCodeAt(0) 是字符 '7' 的 ASCII 码 55,不是数值 0x7E(126)——这就是最常踩的类型错位坑。
为什么不能全程用十六进制字符串通信
因为效率和语义错位:十六进制字符串体积是原始字节的 2 倍(1 字节 → 2 字符),且 WebSocket 协议层不识别“这是十六进制”,它只认 payload 类型(text/binary)和 opcode。强行用字符串传 hex,等于把二进制协议降级为文本协议,还要多一层编解码,还容易因空格、大小写、前导零等引入歧义。
真正需要 human-readable 调试时,只在日志里做 bytesToHex();传输链路中,始终保持原始字节流。协议设计阶段就该约定好字段长度、字节序、校验方式——十六进制只是人眼阅读的表示法,不是数据格式本身。

















