亲爱的 stackoverflow 论坛,
我的 C 服务器和客户端 (javascript) 之间的通信存在问题。我使用 Rasperry Pi 4 作为服务器,Chrome 作为浏览器(我还使用 Firefox 和 Edge 测试了我的东西)。
我的问题是握手的帧头是什么样的。握手应将通信协议从 HTTP 更改为 websocket。我的标题看起来像这样:
GET / HTTP/1.1
Host: 192.168.1.100:8000
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/119.0.0.0 Safari/537.36
Upgrade: websocket
Origin: http://192.168.1.100
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Sec-WebSocket-Key: 6Hw/S8rXFY4ExVDMGWWn6Q==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
服务器端的回答(附生成响应请求的代码):
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 57dCnQc8YJrJ51osdI/I71QHYi4=
现在我在浏览器中收到消息:
script.js:8 WebSocket connection to 'ws://192.168.1.100:8000/' failed: Invalid frame header.
在wireshark中,我可以看到帧头看起来与上面的完全一样。浏览器(客户端)以红色突出显示的消息进行响应:响应中设置了重置标志。
有人看到帧头中有错误吗?或者哈希码可能是错误的?
图比
我找到了一个解决方案,我对传入数据的处理错误。数据必须像这样解码:
int rxDataLen = 0;
char rxBuf[rxBufferSize];
char selectedObject;
int16_t controlledValue;
WH_Status_t ret = OK;
uint8_t k = 0;
char rxBuf[rxBufferSize];
int rx_data_len = recv (comSockId, (void *)rxBuf, rxBufferSize, MSG_DONTWAIT);
// Has a new WebSocket message have been received
if (rx_data_len > 0) {
rxBuf[rx_data_len] = '\0';
// Is the message a handshake request
if (strncmp(rxBuf, "GET", 3) == 0) {
printf("%s\n", rxBuf);
// Yes -> create the handshake response and send it back
char response[WS_HS_ACCLEN];
get_handshake_response(rxBuf, response);
send(comSockId, (void *)response, strlen(response), 0);
printf("Handshake done\n");
}
else {
/* No -> decode incoming message,
process the command and
send back an acknowledge message */
char command[rx_data_len];
decode_incoming_request(rxBuf, command);
command[strlen(command)] = '\0';
/* Check, if the website has been closed. */
if (strncmp(command, "close", 5) == 0){
printf("Cliend closed connection.\n");
return closeClient;
}
// Decode the message string to control the webhouse.
analyseMessage((char*)&command, &selectedObject, &controlledValue);
char response[6] = {0};
sendMessage((char*)&(response), &selectedObject, actualTemperature, alarmState);
printf("Answer: %s\n", response);
char codedResponse[strlen(response)+1];
code_outgoing_response (response, codedResponse);
send(comSockId, (void *)codedResponse,
strlen(codedResponse), 0);
}
}
当连接处于活动状态时,您必须循环执行此代码行,直到连接关闭或从服务器端关闭它。这样,就不再存在无效的帧头。