这个客户端code.server连续发送数据。这里我正在查看13(Header Length)字节消息,获取在消息本身中编码的数据大小,并创建MESSAGE_HEADER_LENGTH + DATA-LENGTH的缓冲区大小。
获取总消息大小后,我使用第二个recv从套接字读取数据。 在初始连接设置和服务器到客户端之间交换hello消息时,它工作正常但是当服务器发送连续流时说(当我们在客户端服务器上的clieck按钮发送具有5000ms间隙的固定长度的连续消息时)recv无法正常工作recv buffer接收原始消息,前面是垃圾或一些空字符串。
#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;
}
}
}
}
}
}
}
答案 0 :(得分:1)
您的代码存在一些问题:
delete[]
在传递空指针时是NOP?pRecvBuffer
是空指针,最后是return 0
,而(可怕的)catch(...)
则不是?catch(...)
抓住所有内容一般都是一个可怕的想法,特别是如果你不重新抛出?有平台(MS),catch(...)
甚至可以捕获段错误。你认为在你的程序中遇到段错之后你觉得安全吗?无论如何,我认为您观察到的问题的根源在于
if(nRecvRetVal > 0)
原因是您只是检查实际上是否能够读取一些字节,但是您没有检查实际接收的字节数(recv
返回的读取字节数可能小于呼叫中指定的号码)。
将结果缓冲区传递给处理函数时,实际上可能会处理随机存储器,就像从网络接收到它一样。
您也可以尝试使用wireshark之类的工具来实际查看您的程序从网络接收的数据包。