Helo. Я работаю над библиотекой 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 для тестирования я перепробовал все. пожалуйста, дайте мне несколько советов
кадрирование данных В разделе RFC6455 показано, что сообщения websocket не являются обычным текстом и не заканчиваются на ноль. Вы не можете использовать функции обработки строки C, такие как strlen
или же strcat
на сообщения, которые вы читаете.
Если вы хотите продолжать использовать строки C, используйте n
определить количество прочитанных байтов и strncpy
добавить это в буфер. Поскольку вы пишете сервер на C ++, вам, вероятно, будет проще, если вы перейдете на использование std::string
вместо.
Разница в обработке сообщений около 128 символов, вероятно, связана с тем, что количество байтов, используемых для указания длины сообщения, увеличивается для полезных нагрузок, превышающих 125 байтов. Для сообщений длиной от 126 до 255 байтов в расширенной длине полезной нагрузки будет нулевой байт. Ваш код будет (неправильно) интерпретировать это как терминатор строки C.
Символ char * не обязательно является строкой C, он должен быть правильно завершен.
while ((n = recv(client_id, buf, BUFLEN, 0)) > 0) {
strcat(new_buffer, buf);
....
Эта проблема с заклинаниями, независимо от того, что получено в buf, не может быть завершена ‘\ 0’.
и когда вы вызываете strcat, это не сработает.
ознакомьтесь с руководством по strcat и strncat функция, убедитесь, что вы используете эти функции правильно.