Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 位操作的结果与节点中的预期不符_Javascript_Node.js_Websocket_Bit Manipulation - Fatal编程技术网

Javascript 位操作的结果与节点中的预期不符

Javascript 位操作的结果与节点中的预期不符,javascript,node.js,websocket,bit-manipulation,Javascript,Node.js,Websocket,Bit Manipulation,我正在Node.js中构建一个websocket服务器实现(我知道Socket.IO是一个东西,但我喜欢使用较低级别的协议实现,以便更好地了解它们的工作原理)。我已经成功地通过了握手阶段,我正在研究一个frame对象,它将把帧中比特的组成解码成一个更高层次的抽象,它是什么样的帧 解码帧的有效负载时,需要使用帧头中提供的屏蔽序列,并执行如下按位异或: this.DECODED = []; for (var i = 0; i < this.PAYLOAD_DATA.length; i++) {

我正在Node.js中构建一个websocket服务器实现(我知道Socket.IO是一个东西,但我喜欢使用较低级别的协议实现,以便更好地了解它们的工作原理)。我已经成功地通过了握手阶段,我正在研究一个frame对象,它将把帧中比特的组成解码成一个更高层次的抽象,它是什么样的帧

解码帧的有效负载时,需要使用帧头中提供的屏蔽序列,并执行如下按位异或:

this.DECODED = [];
for (var i = 0; i < this.PAYLOAD_DATA.length; i++) {
    this.DECODED.push(this.PAYLOAD_DATA[i] ^ this.MASKING_KEY[i % 4]);
}

构造函数被传递一个缓冲区,即帧,然后将其转换为每个字节中位的字符串表示数组,然后根据websockets RFC的规范设置其他属性。我认为问题最有可能是位的XORing字符串表示,而不是字节/十六进制值,尽管我尝试将位字符串转换为整数(带二进制基数的parseInt),但XOR仍然会产生乱码。(平心而论,与预期字符串的文本模式相匹配的是胡言乱语,仅使用移位的字符值,因此您将获得两个连续的随机utf-8字符,而不是两个连续的“L”)。有没有办法将1和0组成的字符串转换回字节对象?到目前为止,我一直不成功。

这样的工作对你有用吗?它将二进制1/0的字符串转换为字节。仅当设置了此掩码时才需要掩码。你们检查过了吗?我认为当前的WebSocket规范是,若并没有设置掩码(至少若源于客户端),那个么它将被拒绝?“在WebSocket协议中,数据是使用帧序列传输的。为了避免混淆网络中介(如拦截代理)以及出于第10.3节中进一步讨论的安全原因,客户端必须屏蔽其发送到服务器的所有帧(有关详细信息,请参阅第5.3节)。”,我检查了。@AWolf试过了,但结果还是这样:
SocketFrame{FIN:'1',RSV1:'0',RSV2:'0',RSV3:'0',OP_code:'TEXT',MASK:'1',MASK_OFFSET:0,PAYLOAD_LENGTH:13,MASKING_KEY:[23113016381],PAYLOAD_数据:[175; 231207,61,136,162,240,52,149,244,198,35,198],解码:[72,101,108,108,111,32,83,101,114,118,101,114,33],解码字符串:'rāĈĈđ2āĔĔĔ3'}
(解码应该是“你好服务器!”@AWolf实际上,它确实有效。我只需要从这行
返回字符串中删除
parseInt
class SocketFrame{
constructor(buffer){
    console.log(buffer.length);
    let bitBytes = buffer.toString('hex').match(/.{1,2}/g).map(hexToBin);
    this.FIN = (bitBytes[0][0]);
    this.RSV1 = (bitBytes[0][1]);
    this.RSV2 = (bitBytes[0][2]);
    this.RSV3 = (bitBytes[0][3]);
    this.OP_CODE = OPCODE_DICTIONARY[bitBytes[0].slice(4)]
    this.MASK = bitBytes[1][0];
    this.MASK_OFFSET = 0;
    this.PAYLOAD_LENGTH = parseInt(bitBytes[1].slice(1), 2);
    if(this.PAYLOAD_LENGTH === 126){
        this.PAYLOAD_LENGTH = parseInt(bitBytes[2] + bitBytes[3], 2);
        this.MASK_OFFSET = 2;
    }
    if(this.PAYLOAD_LENGTH === 127){
        this.PAYLOAD_LENGTH = parseInt(bitBytes[4] + bitBytes[6] + bitBytes[7] + bitBytes[8], 2);
        this.MASK_OFFSET = 6;
    }
    //this.MASKING_KEY = [bitBytes[2 + this.MASK_OFFSET], bitBytes[4 + this.MASK_OFFSET], bitBytes[4 + this.MASK_OFFSET], bitBytes[5 + this.MASK_OFFSET]];
    this.MASKING_KEY = [buffer[2 + this.MASK_OFFSET], buffer[4 + this.MASK_OFFSET], buffer[4 + this.MASK_OFFSET], buffer[5 + this.MASK_OFFSET]];
    // this.MASKING_KEY = this.MASKING_KEY.map((val)=>{return String.fromCharCode(parseInt(val))});
    // this.PAYLOAD_DATA = bitBytes.slice(6 + this.MASK_OFFSET);
    this.PAYLOAD_DATA = buffer.slice(6 + this.MASK_OFFSET);
    this.DECODED = [];
    for (var i = 0; i < this.PAYLOAD_DATA.length; i++) {
        this.DECODED.push(this.PAYLOAD_DATA[i] ^ this.MASKING_KEY[i % 4]);
    }
    this.DECODED_STRING = this.DECODED.map((val)=>{
        return String.fromCharCode(parseInt(val, 2))
    }).join("");
    console.log(this);
}
}