简单的C ++ websocket服务器,可以接收消息,但在发送消息时失败并显示“failed:Invalid frame header”

时间:2022-04-13 09:50:23

I am trying to make a simple websocket server in C++. I can connect to my server from my html/javascript page with:

我试图用C ++创建一个简单的websocket服务器。我可以从我的html / javascript页面连接到我的服务器:

socket = new WebSocket("ws://127.0.0.1:6001/websocket");

my server gets the following request

我的服务器收到以下请求

GET /websocket HTTP/1.1
Host: 127.0.0.1:6001
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://127.0.0.1:6001
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
DNT: 1
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8
Sec-WebSocket-Key: 4oyuqbJMJVtGRvVOd8KWKA==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

and I reply with

我回答

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: QQphkELDd37KE7awCUPSOhWJI1k=

all good so far. I am able to send messages to my server with

到目前为止都很好。我可以用我的服务器发送消息

socket.send("Hello World!");

which the server can successfully decode

服务器可以成功解码

Received data = ��56A$}S-HZKGZ%
---- WebsocketMessage ----
final        = 1
rsv1         = 0
rsv2         = 0
rsv3         = 0
optcode      = 1
masked       = 1
payload size = 12
payload      = Hello World!
--------------------------

but when I try to send a message from my server to my webpage, I always get the following error (chrome console):

但是当我尝试从我的服务器向我的网页发送消息时,我总是收到以下错误(chrome控制台):

WebSocket connection to 'ws://127.0.0.1:6001/websocket' failed: Invalid frame header

Here's the code where I generate the frame (it's in a class so i'll include the member variables below too, all the variables are initialized earlier):

这是我生成框架的代码(它在一个类中,所以我也将包含下面的成员变量,所有变量都在前面初始化):

  bool                final_msg;
  bool                rsv[3] = { false, false, false };
  int                 optcode;
  bool                masked;
  unsigned long long  payload_size;

  std::string encode() {
      std::string msg;
      msg.push_back(
          (char) (final_msg ? 0x80 : 0x00) | (rsv[0] ? 0x40 : 0x00) | (rsv[1] ? 0x20 : 0x00) |
              (rsv[2] ? 0x10 : 0x00) | (0x0F & optcode)
      );
      msg.push_back(
          (char) (masked ? 0x80 : 0x00) | (0x7F & payload_size)
      );
      msg += payload;
      return msg;
  }

For now this function only works at packing messages < 126 bytes. Well, it's suppose to work but according to chrome it doesn't seem to. Here's the binary output for a test (PING) message:

目前,此功能仅适用于打包<126字节的消息。嗯,它假设工作,但根据铬它似乎没有。这是测试(PING)消息的二进制输出:

1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0

From the specs this should work and "socket.onmessage" should fire on my page, instead "onerorr" fires with "event.data = undefined".

根据规范,这应该工作,并且“socket.onmessage”应该在我的页面上触发,而“onerorr”触发“event.data = undefined”。

Can anyone see where i'm going wrong? Or have any idea's how get some more helpful information? Thanks!

谁能看到我哪里出错了?或者有任何想法如何获得更多有用的信息?谢谢!

1 个解决方案

#1


0  

Looks like I was just doing some incorrect encoding for the payload size. The function should read:

看起来我只是对有效负载大小做了一些不正确的编码。该函数应为:

std::string encode() {
    std::string msg;
    msg.push_back(
        (char) (final_msg ? 0x80 : 0x00) | (rsv[0] ? 0x40 : 0x00) | (rsv[1] ? 0x20 : 0x00) |
            (rsv[2] ? 0x10 : 0x00) | (0x0F & optcode)
    );
    msg.push_back(
        (char) (masked ? 0x80 : 0x00) | (0x7F & payload_size)
    );
    msg += payload;
    return msg;
}

Thanks Myst and gre_gor for spotting this.

感谢Myst和gre_gor发现了这一点。

#1


0  

Looks like I was just doing some incorrect encoding for the payload size. The function should read:

看起来我只是对有效负载大小做了一些不正确的编码。该函数应为:

std::string encode() {
    std::string msg;
    msg.push_back(
        (char) (final_msg ? 0x80 : 0x00) | (rsv[0] ? 0x40 : 0x00) | (rsv[1] ? 0x20 : 0x00) |
            (rsv[2] ? 0x10 : 0x00) | (0x0F & optcode)
    );
    msg.push_back(
        (char) (masked ? 0x80 : 0x00) | (0x7F & payload_size)
    );
    msg += payload;
    return msg;
}

Thanks Myst and gre_gor for spotting this.

感谢Myst和gre_gor发现了这一点。