eat_a_lemon
eat_a_lemon

Reputation: 3208

C socket recv returns number of bytes but nothing in the buffer

I have 2 programs a client and a server. The client sends a 4 byte ascii command

client command: BD?\r
server reads: 

server code

while(1) {

    int numbytes = 0;
    printf("MAIN: waiting for commands\n");
    memset(theRecvBuffer, '\0', THE_BUFFER_SIZE);
    numbytes = recv(theCSock, theRecvBuffer, THE_BUFFER_SIZE, 0);
    if(numbytes == 0) {
        printf("client socket closed\n");
        break;
    }
    if(numbytes == -1) {
        printf("cmd loop received socket error: %s\n", strerror(errno));
        break;
    }
}

The server's recv call is returning 4 bytes but the buffer is filled with NULL bytes. Is there anything that could cause the recv call to lose the buffer information? Is there anyway I can debug what is going on in the recv call with print statements? I am limited since this program is on a device with a different chipset so I can't use a debugger. The errno does not help because there is no error since it returns 4 bytes.

Upvotes: 2

Views: 2466

Answers (4)

eat_a_lemon
eat_a_lemon

Reputation: 3208

It was a shared buffer in two different threads on two different sockets that I missed.

Upvotes: 0

evil otto
evil otto

Reputation: 10582

If your code snippet is in fact literally taken from your code (which I doubt) then the problem is obvious: you clear the buffer before every call to recv. Reading 4 bytes goes

clear buffer
recv() = 4
not 0 (eof)
not -1 (error)
loop
clear buffer
recv() = 0
is 0 (eof)
break
loop exits with cleared buffer

Upvotes: 1

mathematician1975
mathematician1975

Reputation: 21351

If you are using multiple threads, there is a possibility that another thread fails to read your buffer before your memset function zeros it in your main loop. This is just a guess but without the complete code it is hard to give a certain answer.

Upvotes: 1

hroptatyr
hroptatyr

Reputation: 4809

strace -e trace=recv -s 65535 -v -p PID

should show you what the buffer looked like after the syscall before the user space gets to see it again. The -s is the buffer size for strings to capture. Optionally -x might be helpful if it's binary data.

Upvotes: 0

Related Questions