2011-03-11 92 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