Poco WebSocket 抛出 Malformed url 异常。为什么?

Poco WebSocket throwing Malformed url exception. Why?

我正在使用 Poco 和 c++ 编写服务器端 WebSocket。现在我正在尝试接受升级到 WebSocket 的 HTTP 请求。当我测试它时,它抛出一个错误,指出请求格式错误。于是在gdb中打开,打印出请求,发现确实不是普通的WebSocket升级请求。这是 GDB 输出。

(gdb) x/518xb buf
0x7fffffffb920: 0x16    0x03    0x01    0x02    0x00    0x01    0x00    0x01
0x7fffffffb928: 0xfc    0x03    0x03    0x8c    0x36    0x36    0x84    0x63
0x7fffffffb930: 0x9b    0x72    0x68    0x55    0xe2    0xad    0x61    0x63
0x7fffffffb938: 0xd8    0x05    0x94    0x69    0x6a    0x2e    0xf5    0x09
0x7fffffffb940: 0xac    0x10    0xc5    0xe8    0x6b    0x93    0x87    0x8f
0x7fffffffb948: 0x34    0xf6    0x4e    0x20    0xe6    0x1c    0x52    0xd6
0x7fffffffb950: 0x39    0xd4    0x46    0xae    0x03    0xe5    0x92    0xf3
0x7fffffffb958: 0x56    0x2e    0x33    0xc7    0x30    0x9a    0xc8    0xbd
0x7fffffffb960: 0xc6    0x72    0x82    0x47    0x2f    0x9a    0x2d    0xb4
0x7fffffffb968: 0x43    0x77    0x6d    0xbb    0x00    0x24    0x13    0x01
0x7fffffffb970: 0x13    0x03    0x13    0x02    0xc0    0x2b    0xc0    0x2f
0x7fffffffb978: 0xcc    0xa9    0xcc    0xa8    0xc0    0x2c    0xc0    0x30
0x7fffffffb980: 0xc0    0x0a    0xc0    0x09    0xc0    0x13    0xc0    0x14
0x7fffffffb988: 0x00    0x33    0x00    0x39    0x00    0x2f    0x00    0x35
0x7fffffffb990: 0x00    0x0a    0x01    0x00    0x01    0x8f    0x00    0x00
0x7fffffffb998: 0x00    0x0e    0x00    0x0c    0x00    0x00    0x09    0x6c
0x7fffffffb9a0: 0x6f    0x63    0x61    0x6c    0x68    0x6f    0x73    0x74
0x7fffffffb9a8: 0x00    0x17    0x00    0x00    0xff    0x01    0x00    0x01
0x7fffffffb9b0: 0x00    0x00    0x0a    0x00    0x0e    0x00    0x0c    0x00
0x7fffffffb9b8: 0x1d    0x00    0x17    0x00    0x18    0x00    0x19    0x01
0x7fffffffb9c0: 0x00    0x01    0x01    0x00    0x0b    0x00    0x02    0x01
0x7fffffffb9c8: 0x00    0x00    0x23    0x00    0x00    0x00    0x10    0x00
0x7fffffffb9d0: 0x0e    0x00    0x0c    0x02    0x68    0x32    0x08    0x68

只要快速看一下十六进制就可以看出它不是常规字符。有很多非字母数字字符。但是当我在浏览器中检查网络 activity 时,它显示了请求的文本,一目了然。那么,为什么我的程序接收的字节与浏览器声称发送的字节不同?

服务器端(C++):

#include <iostream>
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponseImpl.h"
#include "Poco/Net/HTTPServerRequestImpl.h"
#include "Poco/Net/HTTPServerConnection.h"
#include "Poco/Net/HTTPServerParams.h"
#include "Poco/Net/HTTPServerSession.h"

#define PORT (unsigned short) 3000
#define MAX_BYTES 9999
int main()
{
        Poco::Net::ServerSocket x(PORT);
        Poco::Timespan timeout(25000000);
        char buf[MAX_BYTES];
        memset(buf,0,MAX_BYTES);
        if (x.poll(timeout, 1)) {
                Poco::Net::StreamSocket ss = x.acceptConnection();
                int i = ss.receiveBytes(buf, MAX_BYTES);
                printf("received %d bytes, %s\n", i, buf);
        }
        return 0;
}

客户端(javascript):

$(document).ready(function() {
    webSoc = new WebSocket("wss://localhost:3000");
    webSoc.onopen = function (event) {
        $("#c").click(function () {
            webSoc.send("Hello, World!\n");
        });
    }
});

我只差一个字就搞定了。我将 "wss://localhost:3000" 更改为 "ws://localhost:3000"

wss 代表 WebSocket 安全。所以,我的 websocket 在发送之前加密了数据。服务器端套接字试图将其解释为未加密,并正确地发现它对于未加密的套接字格式不正确。

您正在通过 wss 连接,这意味着连接将使用 SSL 或 TLS 加密。这些以握手开始,这是第一个 0x16 字节。接下来是加密类型,0x03 0x01 (TLS 1.0),然后是长度 2 个字节。然后 0x01 表示客户端问候等等。所以这是完全正常的。

如果您想使用普通 HTTP 会话,请使用 ws 协议。