首页 > 解决方案 > Windows vc++ websocket E_INVALID_PROTOCOL_FORMAT

问题描述

一直在制作一个工作应用程序,当您在锁定屏幕上敲击键盘时自动接听我的软电话上的电话,这样我在房间另一端就不会错过它。

我看到 windows 有 web sockets,所以我想用他们的一个来防止链接库。

我创建了一个websocket 句柄

if (WebSocketCreateClientHandle(NULL, 0, &socket_handle) != S_OK) {
    Log::LogMessage("WebSocketCreateClientHandle Failed", Log::LOGLEVEL::CRITICAL);
    return 1;
}

然后运行​​WebSocketBeginClientHandshake

// if handshake is successful, these will be populated
WEB_SOCKET_HTTP_HEADER* responceHeaders = nullptr;
ULONG responceHeadderCount;
if (WebSocketBeginClientHandshake(socket_handle, NULL, 0, NULL, 0, &headers[0], 1, &responceHeaders, &responceHeadderCount) != S_OK) {
    return -1;
}

这返回了 S_OK。然后我写出这样的标题数组:

// name nameLength, value valuelength
for (int i = 0; i < responceHeadderCount; i++) {
    std::cout << responceHeaders[i].pcName << "x" << responceHeaders[i].ulNameLength << ":" << responceHeaders[i].pcValue << "x" << responceHeaders[i].ulValueLength << std::endl;
}

这表明:

Sec-WebSocket-Keyx17:r7XbrevEUv6awqPe24f0Ww==┐å⌐≤w2x24
Connectionx10:Upgradex7
Upgradex7:websocketx9
Sec-WebSocket-Versionx21:13x2

然后我将这些标头传递给WebSocketEndClientHandshake以及一些 ULONG 指针:

ULONG selected_subprotocol;
ULONG selected_extensions;
ULONG selected_extensions_count;
HRESULT result = WebSocketEndClientHandshake(socket_handle, responceHeaders, responceHeadderCount, &selected_extensions, &selected_extensions_count, &selected_subprotocol);

我遇到的问题是WebSocketEndClientHandshake。它总是返回 E_INVALID_PROTOCOL_FORMAT。

我修改了我的 Host 标头以将服务器地址设置为无意义的“sdfkbsdf”以查看它的作用,并且看不到任何变化,BeginHandshake 仍然成功,而 EndHandshake 失败。所以我想知道这是否与我的 Host 标头有关,其结构如下:

WEB_SOCKET_HTTP_HEADER* host = new WEB_SOCKET_HTTP_HEADER;
PCHAR phost = (char*)"Host";
PCHAR pValue = (char*)"https://www.w3.org:80";
host->pcName = phost;
host->ulNameLength = sizeof(phost);
host->pcValue = pValue;
host->ulValueLength = sizeof(pValue);
headers.push_back(*host);

有谁知道这里有什么问题?我已经尝试将我的标头添加到 BeginClientHandshake 返回的标头数组中,并将其发送到 EndClientHandshake 以查看是否有所作为,没有运气。

标签: c++visual-c++websocket

解决方案


WebSocket 协议组件 API 提供:

... 支持客户端和服务器握手相关的 HTTP 标头,验证接收到的握手数据,并解析 WebSocket 数据流。它不处理任何特定于 HTTP 的操作(重定向、身份验证、代理支持),也不执行任何 I/O 操作(发送或接收 WebSocket 流字节)。

(来自文档

该 API 不包括传输,它需要 HTTP 才能工作。为了进行握手,您必须:

  • 创建一个 HTTP GET 请求以ws://host.com:1234/path?q
  • 将请求标头传递给WebSocketBeginClientHandshake()
  • 将返回的附加标头添加到请求中
  • 发送请求并接收响应(必须是HTTP 101 Switching Protocols响应码)
  • 将响应标头传递给以WebSocketEndClientHandshake()获取返回码

您可以使用套接字或管道作为传输。不过,对于您的用例,仅使用WinHttp的 websocket 函数可能会更容易。


推荐阅读