直升机。我正在使用C ++ Websocket库。一切都很好,直到出现一个奇怪的问题。
int n = 0, n_add = 0;
char *buf = (char*)malloc(BUFLEN);
char new_buffer[4096];
while ((n = recv(client_id, buf, BUFLEN, 0)) > 0) {
strcat(new_buffer, buf);
int new_buffer_length = strlen(new_buffer);
int buf_length = strlen(buf);
n_add+= n;
// debug
cout << "buf: '" << buf << "'" << endl;
cout << "new_buffer_length: '" << new_buffer_length << "'" << endl;
cout << "buf_length: '" << buf_length << "'" << endl;
cout << "n: '" << n << "'" << endl;
cout << "n_add: '" << n_add << "'" << endl;
memset(buf, '\0', BUFLEN);
if (n_add == new_buffer_length && n < BUFLEN) {
cout << "new_buffer: '" << new_buffer << "'" << endl;
// if client is already connected
if (ws_clients[client_id][2] == WS_READY_STATE_OPEN) {
this->ws_client_message(client_id, new_buffer, new_buffer_length);
}
// if client needs a handshake
if (ws_clients[client_id][2] == WS_READY_STATE_CONNECTING) {
this->ws_client_handshake(client_id, new_buffer);
}
memset(&new_buffer, '\0', 4096);
n_add = 0;
FD_ZERO(&this->tmp_fds);
}
}
完成握手以及任何小于126的有效负载。当发生这种情况时,我得到:
buf: 'þ'
new_buffer_length: '2'
buf_length: '2'
n: '128'
n_add: '128'
buf: '½HÆA¯J'
new_buffer_length: '8'
buf_length: '6'
n: '6'
n_add: '134'
n说我收到了128个字节,但它实际上只有2个,第二次给了我6个字节,那些都没问题。如果我改变我的BUFLEN(限制为128并且放到2),我将一切都搞定,除了最后一个循环,它永远不会达到134,即实际的有效载荷长度。
好的,如果每个人都有任何想法,我使用http://www.websocket.org/echo.html进行测试,我尝试了一切。请给我一些提示
答案 0 :(得分:0)
RFC6455的data framing部分显示websocket消息不是纯文本,也不是以空字符结尾的字符串。您不能对您阅读的邮件使用strlen
或strcat
等C字符串处理函数。
如果要继续使用C字符串,请使用n
确定已读取的字节数,并使用strncpy
将其添加到缓冲区。既然你正在编写一个C ++服务器,那么如果你转而使用std::string
,你可能会发现更容易。
处理大约128个字符的消息的差异可能来自以下事实:用于指示消息长度的字节数增加了超过125个字节的有效负载。对于126到255字节长的消息,扩展的有效负载长度中将有一个零字节。您的代码将(错误地)将其解释为C字符串的终止符。
答案 1 :(得分:0)
char *不一定是C字符串,必须正确终止。
while ((n = recv(client_id, buf, BUFLEN, 0)) > 0) {
strcat(new_buffer, buf);
....
这个法术问题,无论在buf中收到什么,都可能不会被'\ 0'终止。 当你调用strcat时,它将无法工作。
查看strcat手册和 strncat 函数,确保正确使用这些函数。