0

へろ。私は C++ Websocket ライブラリに取り組んでいます。奇妙な問題が 1 つ現れるまでは、すべて問題ありませんでした。

    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 だけです。2 回目には 6 バイトが返され、それらは問題ありません。128 に制限されている BUFLEN を 2 に変更すると、最後のループを除いて、実際のペイロード長である 134 に到達することはありません。

わかりましたので、誰もが何か考えがあれば、私はhttp://www.websocket.org/echo.htmlをテストに使用しています。すべてを試しました。ヒントを教えてください

4

2 に答える 2

0

char* は必ずしも C 文字列であるとは限りません。適切に終了する必要があります。

while ((n = recv(client_id, buf, BUFLEN, 0)) > 0) {
    strcat(new_buffer, buf);
    ....

このスペルの問題は、buf で受け取ったものが '\0' で終了しない可能性があります。strcat を呼び出すと、機能しません。

strcat およびstrncat関数のマニュアルをチェックアウトし、これらの関数を正しく使用していることを確認してください。

于 2013-01-20T15:59:43.153 に答える
0

RFC6455のデータ フレーミングセクションは、Websocket メッセージがプレーン テキストではなく、null で終わる文字列でもないことを示しています。読んだメッセージに対してstrlenやのような C 文字列処理関数を使用することはできません。strcat

C 文字列を引き続き使用する場合は、 を使用nして、読み取ったバイト数を特定し、strncpyそれをバッファーに追加します。std::stringただし、C++ サーバーを作成しているので、代わりに使用するように切り替えると、おそらく作業が簡単になります。

128 文字前後のメッセージの処理の違いは、メッセージの長さを示すために使用されるバイト数が、125 バイトを超えるペイロードの場合に増加するという事実に起因すると考えられます。長さが 126 ~ 255 バイトのメッセージの場合、拡張ペイロード長には 0 バイトが含まれます。コードはこれを (誤って) C 文字列のターミネータとして解釈します。

于 2013-01-20T15:56:23.497 に答える