简体   繁体   中英

socket Recv api return unexpected Value

this the client code.server send data continuously.Here I am peeking the 13 (Header Length)byte message getting the size of the data which is encoded in the message itself and creating the buffer size of MESSAGE_HEADER_LENGTH + DATA-LENGTH.

after getting total message size I am using second recv to read data from the socket. during initial connection setup and exchange of hello message between server to client it is working fine but when server sending continuous stream say(when we clieck button at client server send continuous message of fixed lenght with the gap of 5000ms) recv is not working properly and recv buffer receives original message preceded by garbage or some time empty string.

#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;
                        }
                    }
                }
            }
        }
    }
}

Your code has a few problems:

  1. Do you know that delete[] is a NOP when passed a null pointer?
  2. Why in the first check about pRecvBuffer being the null pointer you end up with a return 0 and in the (terrible) catch(...) you don't?
  3. Do you know that catching everything with catch(...) is a terrible idea in general and especially if you don't rethrow? There are platforms (MS) where with catch(...) you even trap segfaults. What do you think it's safe to do after you caught a segfault in your program?

Anyway I think that the source of the problems you observed is in the line

if(nRecvRetVal > 0)

The reason is that you are just checking that you actually were able to read some bytes, but you're not checking how many bytes you actually received ( recv returns the numbers of bytes read that may be less than the number specified in the call). When you pass the resulting buffer to the processing function you're actually potentially processing random memory as if it has been received from the network.

You may also find useful to try tools like wireshark to actually check out exactly what packets your program is receiving from the network.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM