c++ - 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 以查看是否有所作为,没有运气。
解决方案
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 函数可能会更容易。
推荐阅读
- android - Android Studio - 带有大写字母的键盘锁定每个新单词
- email - 由于 msnbot,发送给 Outlook 用户的电子邮件验证链接过期
- r - 从初始化状态更新 reactiveValues
- sql - 基于未排序的列过滤排名
- javascript - 带有静态样式表的 Material UI
- azure-data-explorer - 如何找到 kusto 中所有列的基数?
- python - Pandas 按日期和 id 计数/添加值
- javascript - 为什么我有这个 JavaScript NaN 问题?
- r - 从 R ggplot2 中的某些 geom_line 中删除 geom_point
- javascript - 闪亮服务器脚本导致“日历错误:找不到函数“日历””