C++ 套接字Recv api返回意外值
这是客户端代码。服务器连续发送数据。在这里,我查看13字节(头长度)的消息,获取消息本身编码的数据大小,并创建消息头长度+数据长度的缓冲区大小 在获得总消息大小后,我使用第二个recv从套接字读取数据。 在初始连接设置和服务器到客户端之间的hello消息交换期间,它工作正常,但当服务器发送连续流时,比如说(当我们在客户端服务器上点击按钮发送固定长度的连续消息时,间隔为5000ms)recv工作不正常,recv缓冲区接收到原始消息,消息前面有垃圾或某个时间的空字符串C++ 套接字Recv api返回意外值,c++,tcp,tcpclient,C++,Tcp,Tcpclient,这是客户端代码。服务器连续发送数据。在这里,我查看13字节(头长度)的消息,获取消息本身编码的数据大小,并创建消息头长度+数据长度的缓冲区大小 在获得总消息大小后,我使用第二个recv从套接字读取数据。 在初始连接设置和服务器到客户端之间的hello消息交换期间,它工作正常,但当服务器发送连续流时,比如说(当我们在客户端服务器上点击按钮发送固定长度的连续消息时,间隔为5000ms)recv工作不正常,recv缓冲区接收到原始消息,消息前面有垃圾或某个时间的空字符串 #define MESSAGE
#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;
}
}
}
}
}
}
}
您的代码有几个问题:
delete[]
是NOP吗pRecvBuffer
是空指针的第一次检查中,您会得到一个返回0
,而在(糟糕的)捕获(…)
中却没有catch(…)
捕获所有东西通常是个糟糕的主意,尤其是如果你不重新捕获的话?有些平台(MS)甚至可以通过catch(…)
捕获故障。在你的程序中发现一个错误后,你认为做什么是安全的if(nRecvRetVal > 0)
原因是您只是检查您是否确实能够读取一些字节,而不是检查实际接收的字节数(recv
返回读取的字节数,该字节数可能小于调用中指定的字节数)。
当您将结果缓冲区传递给处理函数时,实际上您可能正在处理随机内存,就好像它是从网络接收的一样
您还可以尝试一些工具,例如实际检查您的程序从网络接收的数据包。您的代码有一些问题:
delete[]
是NOP吗pRecvBuffer
是空指针的第一次检查中,您会得到一个返回0
,而在(糟糕的)捕获(…)
中却没有catch(…)
捕获所有东西通常是个糟糕的主意,尤其是如果你不重新捕获的话?有些平台(MS)甚至可以通过catch(…)
捕获故障。在你的程序中发现一个错误后,你认为做什么是安全的if(nRecvRetVal > 0)
原因是您只是检查您是否确实能够读取一些字节,而不是检查实际接收的字节数(recv
返回读取的字节数,该字节数可能小于调用中指定的字节数)。
当您将结果缓冲区传递给处理函数时,实际上您可能正在处理随机内存,就好像它是从网络接收的一样
您还可以尝试一些工具,例如实际检查您的程序从网络接收到的数据包