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 项的内容,然后告诉我们您希望在OPCMASK 中看到什么 MASK 应该是 1(屏蔽)和 OPC x1(文本)。前 8 个字符:-127,-122,-85,-60,-77,-32,-29,-95。 (使用std::cout &lt;&lt; (int)packet[i] &lt;&lt; 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++)的主要内容,如果未能解决你的问题,请参考以下文章

Python中的WebSocket帧解码

如何将超过 65536 字节的二进制数据编码为 c++ 上的 websocket 帧

Go语言实现WebSocket协议

c++ websocket帧发送导致服务器关闭连接

websocket和websocket++和websocketpp都是啥,有啥关系呢

通过 websocket 发送 STOMP 帧