2013-01-20 61 views
0

Helo。我正在研究C++ Websocket庫。一切都好,直到出現一個奇怪的問題。C++ Websocket recv 2個字節

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時是happends我得到這個:

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個說我recived 128個字節,但實際上它是隻有2中,第二次給我6個字節,這些都沒問題。如果我改變我的限制爲128的BUFLEN並將其設置爲2,那麼除了最後一個循環之外,我會收到一切正常,它永遠不會達到134,實際有效負載長度。

好吧,如果大家有任何想法,我使用http://www.websocket.org/echo.html進行測試,我試了一切。請給我一些提示

+0

它看起來像消息的第三個字節是一個NUL字節('\ 0')。這被'strcat'和'strlen'視爲字符串終結符。 –

+0

是的,顯然第三個字節是NULL字節:)並且從那裏開始下坡。感謝你的快速回復! –

回答

0

RFC6455的data framing部分顯示websocket消息不是純文本,也不是以空字符結尾的字符串。您在閱讀的消息中不能使用C字符串處理功能,如strlenstrcat

如果要繼續使用C字符串,請使用n來確定已讀取的字節數,並使用strncpy將其添加到緩衝區。由於您正在編寫C++服務器,因此如果您改爲使用std::string,您可能會發現更容易。

處理128個字符左右的消息的區別可能來自於這樣一個事實,即用於指示消息長度的字節數增加了超過125個字節的有效負載。對於長度爲126到255字節的消息,擴展有效載荷長度中將有零字節。您的代碼將(錯誤地)將其解釋爲C字符串的終止符。

+0

我使用C字符串,因爲我感覺字符比字符串更舒適。另外,對於他的lib,我需要訪問char數組中的各種字符以獲得OPcode和mask,並且它真的簡化了這個過程,而不是使用substr。感謝您的回覆,我無法相信我在編碼中看不到那個錯誤。我真的很感謝你的速度。 –

0

char *不一定是C字符串,它必須正確終止。

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

此闡明的問題,在任何的buf接收,可能不是 '\ 0' 終止。 當你調用strcat時,它不起作用。

結帳手冊strcat和strncat功能,請確保您正確使用這些功能。

+0

你好。感謝您的答覆;確實strlen會計數,直到第一次出現null,以及strcat會從第一次出現的無效時開始追加,基本上,我的糟糕! –