我正在Node.js中构建一个websocket服务器实现(我知道Socket.IO是一个东西,但我喜欢在更低级别的协议实现上工作,所以我可以更好地理解它们是如何工作的)。我已经设法通过握手阶段,我正在研究一个帧对象,它将帧中位的组成解码为更高级别的抽象,它是什么样的帧。
解码帧的有效负载时,需要使用帧头中提供的掩码序列,并按照以下方式执行按位异或:
this.DECODED = [];
for (var i = 0; i < this.PAYLOAD_DATA.length; i++) {
this.DECODED.push(this.PAYLOAD_DATA[i] ^ this.MASKING_KEY[i % 4]);
}
假设我应该能够将这些值解析为整数,然后使用String.fromCharCode()
来获取他们的角色来组成发送的消息,但是我只是得到了胡言乱语而不是预期的消息(&#34;你好,服务器!&#34;),虽然消息是预期的长度。
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);
}
}
构造函数传递一个缓冲区,即帧,然后将其转换为每个字节中位的字符串表示数组,然后根据websockets RFC的规范设置其他属性。我相信这个问题最有可能是比特的字符串表示,而不是字节/十六进制值,尽管我尝试将位串转换为整数(parseInt带有二进制基数),但XOR仍然产生了乱码。 (公平地说,它是与目标字符串的文本模式匹配的乱码,只是与移位的字符值匹配,因此不是连续两次&#34; L&#34; s,您将获得两个连续的随机utf-8字符)。有没有办法将1s和0s的字符串转换回字节对象?到目前为止,我没有成功。