WebSocket,解码数据帧(c++)
Posted
技术标签:
【中文标题】WebSocket,解码数据帧(c++)【英文标题】:WebSocket, decoding data frame (c++) 【发布时间】:2017-08-31 22:36:20 【问题描述】:我正在使用 winsock2 开发 websocket 服务器(在 c++ 中)。现在,我正在响应来自客户端(在我的情况下为 Chrome)的初始握手,然后我正在从客户端发送数据:
socket.send("Hello!");
我正在尝试解码数据帧,但遇到了一些问题。让我们看一下代码:
int GetBit(const char * data, unsigned int idx)
unsigned int arIdx = idx / 4;
unsigned int biIdx = idx % 4;
return (data[arIdx] >> biIdx) & 1;
void ParseDataFrame(const char * packet)
int FIN = GetBit(packet, 0);
unsigned char OPC = 0;
int opc0 = GetBit(packet, 4);
int opc1 = GetBit(packet, 5);
int opc2 = GetBit(packet, 6);
int opc3 = GetBit(packet, 7);
OPC |= (opc0 << 0);
OPC |= (opc1 << 1);
OPC |= (opc2 << 2);
OPC |= (opc3 << 3);
int MASK = GetBit(packet, 5);
我得到:
FIN = 1
OPC = x6 (can´t be)
MAKS = 0 (can´t be)
我一直在阅读 WS 协议,也许问题出在我的代码中。 提前致谢!
编辑
我想提一下,连接已正确建立,因为控制台 (chrome) 中没有错误,并且调用了 socket.onopen 事件。
【问题讨论】:
能否请您告诉我们const char * packet
中至少前8 项的内容,然后告诉我们您希望在OPC
和MASK
中看到什么
MASK 应该是 1(屏蔽)和 OPC x1(文本)。前 8 个字符:-127,-122,-85,-60,-77,-32,-29,-95
。 (使用std::cout << (int)packet[i] << std::endl
打印它们)
【参考方案1】:
您的数据看起来不错,第一个字节(-127 in dec,或 0x81 或 1000 0001)。
使用GetBit
读取时,每个字节使用 4 位而不是 8 位。
biIdx
目前从最右边的位开始到最左边的位。这应该是相反的:
int GetBit(const char * data, unsigned int idx)
unsigned int arIdx = idx / 8;
unsigned int biIdx = idx % 8;
return (data[arIdx] >> (7 - biIdx)) & 1;
这应该让你得到正确的位。
对于MASK
,您应该阅读第 8 位。如指定:https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
【讨论】:
是的,面具中的 5 是错误的!感谢您指出!每字节使用 8 位是否意味着我必须更改 GetBit 方法? (将 4 替换为 8)谢谢 是的,将GetBit
中的4
替换为8
。我忘记了biIdx
,它目前从最右边开始到最左边。这应该是相反的。你可以这样做:unsigned int biIdx = 7 - (idx % 8);
谢谢,我还得把 OPC |=
的另一个倒过来:)
我一直在想,为什么我必须将每个字节读取为 8 位(而不是 4 位),这是因为消息被编码为 UTF-8 吗?我虽然只有文本有效负载被编码为 UTF-8 而不是孔帧。我错过了什么?
忽略我的最后评论,出于某种原因,我认为1byte = 4 bits
我想我应该回到电脑上做傻瓜:3以上是关于WebSocket,解码数据帧(c++)的主要内容,如果未能解决你的问题,请参考以下文章
如何将超过 65536 字节的二进制数据编码为 c++ 上的 websocket 帧