【问题标题】:Understanding this websocket frame parsing code理解这个 websocket 帧解析代码
【发布时间】:2020-06-03 00:39:40
【问题描述】:

这里的初学者试图从底层了解 websockets 的工作原理。我正在尝试创建自己的实现,但是我对解析从客户端 => 服务器发送的数据帧的逻辑感到非常困惑。

我知道在服务器端接收到的缓冲区由多个字节组成,前两个是主要的标头信息(fin 位、长度、操作码、掩码等)。

我在 SO 上找到了以下代码,它解析了两个字节,并且通过测试,它确实返回了正确的值。

let index = 0;
frame = {
    data: new Buffer(0),
    fin: (buffer[index] & 128) === 128,
    length: buffer[index + 1] & 127,
    masked: (buffer[index + 1] & 128) === 128,
    opcode: buffer[index] & 15
}

我的主要问题是……这究竟是如何返回正确值的?

我知道 buffer[index] 和 buffer[index+1] 指的是第一个和第二个字节,并且 AND 操作数用于比较每个字节的二进制值,当两个数字中的两个索引相等时输出 1为 1,否则为 0……但是……

& 运算符后面的数字是从哪里来的?例如:操作码为 15,长度为 127。

在这两个值上使用 AND 运算符究竟如何得到正确的结果?这是我真的不明白。

如果这是我不理解的基本计算机科学概念,我深表歉意,但如果有人能够向我解释这段代码到底发生了什么,我们将不胜感激。

【问题讨论】:

  • 按位& 返回两个数字的位序列的重叠。如果将一侧的值减少到一位,则可以使用该值“测试”该位是否设置在另一个数字中。这就是128 所做的。它检查字节的 MSB。 15 == 最后 4 位和 127 == 最后 7 位。

标签: javascript node.js websocket binary bit-manipulation


【解决方案1】:

我知道它看起来像一个普通的 AND 比较,但实际上它是一个布尔 AND 比较。

为了更具体一点,操作码的 buffer[index] & 15 表示将 buffer[index] 作为二进制数与 15(这是 websockets 允许的最高操作码)作为二进制数逐位比较并返回二进制结果作为整数,操作码本身告诉正在发送的帧类型。(如果你好奇,可以在这里深入了解https://www.rfc-editor.org/rfc/rfc6455#section-11.8.

关于 127 的长度部分,我参考了 SO 上的这个答案,因为它是一个可靠的答案:how to work out payload size from html5 websocket

有关运算符的进一步阅读,请参阅我的源代码中关于按位逻辑运算符的部分。

来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多