Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 套接字Recv api返回意外值_C++_Tcp_Tcpclient - Fatal编程技术网

C++ 套接字Recv api返回意外值

C++ 套接字Recv api返回意外值,c++,tcp,tcpclient,C++,Tcp,Tcpclient,这是客户端代码。服务器连续发送数据。在这里,我查看13字节(头长度)的消息,获取消息本身编码的数据大小,并创建消息头长度+数据长度的缓冲区大小 在获得总消息大小后,我使用第二个recv从套接字读取数据。 在初始连接设置和服务器到客户端之间的hello消息交换期间,它工作正常,但当服务器发送连续流时,比如说(当我们在客户端服务器上点击按钮发送固定长度的连续消息时,间隔为5000ms)recv工作不正常,recv缓冲区接收到原始消息,消息前面有垃圾或某个时间的空字符串 #define MESSAGE

这是客户端代码。服务器连续发送数据。在这里,我查看13字节(头长度)的消息,获取消息本身编码的数据大小,并创建消息头长度+数据长度的缓冲区大小

在获得总消息大小后,我使用第二个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;
                        }
                    }
                }
            }
        }
    }
}

您的代码有几个问题:

  • 您知道当传递空指针时,
    delete[]
    是NOP吗
  • 为什么在关于
    pRecvBuffer
    是空指针的第一次检查中,您会得到一个
    返回0
    ,而在(糟糕的)
    捕获(…)
    中却没有
  • 你知道吗,用
    catch(…)
    捕获所有东西通常是个糟糕的主意,尤其是如果你不重新捕获的话?有些平台(MS)甚至可以通过
    catch(…)
    捕获故障。在你的程序中发现一个错误后,你认为做什么是安全的
  • 无论如何,我认为你所观察到的问题的根源就在这条线上

    if(nRecvRetVal > 0)
    
    原因是您只是检查您是否确实能够读取一些字节,而不是检查实际接收的字节数(
    recv
    返回读取的字节数,该字节数可能小于调用中指定的字节数)。 当您将结果缓冲区传递给处理函数时,实际上您可能正在处理随机内存,就好像它是从网络接收的一样


    您还可以尝试一些工具,例如实际检查您的程序从网络接收的数据包。您的代码有一些问题:

  • 您知道当传递空指针时,
    delete[]
    是NOP吗
  • 为什么在关于
    pRecvBuffer
    是空指针的第一次检查中,您会得到一个
    返回0
    ,而在(糟糕的)
    捕获(…)
    中却没有
  • 你知道吗,用
    catch(…)
    捕获所有东西通常是个糟糕的主意,尤其是如果你不重新捕获的话?有些平台(MS)甚至可以通过
    catch(…)
    捕获故障。在你的程序中发现一个错误后,你认为做什么是安全的
  • 无论如何,我认为你所观察到的问题的根源就在这条线上

    if(nRecvRetVal > 0)
    
    原因是您只是检查您是否确实能够读取一些字节,而不是检查实际接收的字节数(
    recv
    返回读取的字节数,该字节数可能小于调用中指定的字节数)。 当您将结果缓冲区传递给处理函数时,实际上您可能正在处理随机内存,就好像它是从网络接收的一样

    您还可以尝试一些工具,例如实际检查您的程序从网络接收到的数据包