2011-03-11 116 views
1

這個客戶端code.server連續發送數據。在這裏我正在偷看13(Header Length)字節的消息,獲取消息本身編碼的數據的大小並創建緩衝區大小爲MESSAGE_HEADER_LENGTH +數據長度。套接字Recv api返回意外值

獲取總郵件大小後,我正在使用第二個recv從套接字讀取數據。 在服務器到客戶端之間的初始連接建立和交換hello消息時,它工作正常,但是當服務器發送連續流時說(當我們在客戶端服務器上掛斷按鈕發送固定長度爲5000ms的連續消息時)recv工作不正常並且recv緩衝區接收到以垃圾或一段時間爲空的字符串之前的原始消息。

#define MESSAGE_HEADER_LENGTH 13 

... 

while { 
    nSelectRetVal = select(NULL, &fdRead,NULL, &fdExcept, &tv); 
    if(nSelectRetVal > 0) { 
     if(FD_ISSET(pControlMgr->GetConnectionMgr()->GetUDPSocket(), 
        &fdRead)) { 
      try { 
       char chHeaderBuffer[MESSAGE_HEADER_LENGTH + 1]; 
       memset(chHeaderBuffer,0,MESSAGE_HEADER_LENGTH + 1); 
       int nMsgPeek = recv(pControlMgr->GetConnectionMgr()->GetUDPSocket(), 
            chHeaderBuffer, MESSAGE_HEADER_LENGTH, MSG_PEEK); 
       chHeaderBuffer[MESSAGE_HEADER_LENGTH] = '\0'; 
       if(nMsgPeek == SOCKET_ERROR) 
        return 0; 
       CProtocolMgr objProtocolMgr; 
       int Bufferlength = objProtocolMgr.ProtocolMsgSize(chHeaderBuffer) + MESSAGE_HEADER_LENGTH; 
       pRecvBuffer = new char[Bufferlength]; 
       memset(pRecvBuffer, 0, Bufferlength); 
       int nRecvRetVal = recv(pControlMgr->GetConnectionMgr()->GetUDPSocket(), 
             pRecvBuffer, Bufferlength, 0); 
       if(nRecvRetVal > 0) { 
        if(pControlMgr->HandlePacket(pRecvBuffer, 
               pControlMgr->GetConnectionMgr()->GetServerAddress()) == -1) { 
         if(NULL != pRecvBuffer) { 
          delete [] pRecvBuffer; 
          pRecvBuffer = NULL; 
          return 0 ; 
         } 
        } catch(...) { 
         if(NULL != pRecvBuffer) { 
          delete [] pRecvBuffer; 
          pRecvBuffer = NULL; 
         } 
        } 
       } 
      } 
     } 
    } 
} 

回答

1

您的代碼有幾個問題:

  1. 你知道delete[]是NOP傳遞空指針?
  2. 爲什麼在第一次檢查pRecvBuffer是空指針,你最終得到一個return 0和在(可怕的)catch(...)你不?
  3. 你是否知道,捕捉一切與catch(...)是一個一般的可怕的想法,特別是如果你不rethrow?有平臺(MS)與catch(...)你甚至陷阱段錯誤。在您的程序中發現段錯誤後,您認爲安全嗎?

無論如何,我認爲你觀察到的問題的根源是在該行

if(nRecvRetVal > 0) 

的原因是,你只是檢查,你居然也能看懂一些字節,但你不檢查您實際收到的字節數(recv返回讀取的字節數,可能小於調用中指定的數量)。 將結果緩衝區傳遞給處理函數時,您實際上可能會處理隨機存儲器,就好像它已從網絡中收到一樣。

您也可能會發現嘗試使用像wireshark這樣的工具可以真正檢查您的程序從網絡接收的數據包。

+0

這是邏輯錯誤。現在它工作正常 – 2011-03-11 08:15:30