tags:

views:

81

answers:

3

I'm writing simple server/client in c, where server temporary stores message from client and retrieve it when client request it.

The problem is when client receives message from server, the buffer acts kinda weird. All i did is read as much as receive from server and print it on the screen, but somehow buffer was overwrited more than maximum size of buffer

in client

while((byteRead = recv(ssock, buffer, MAXBUF, 0)) > 0)
{
   if(byteRead <= 0)
       break;
    printf("%s", buffer);
}

where MAXBUF is 256. It keep contains some garbages so i examined the string size in buffer and surprisingly

printf("%d READ vs %d buffer strlen \n", byteRead, strlen(buffer))

show me that byteRead is 256 but string length of buffer is 262.

Any idea??

P.s on server side, it reads file correctly and send it onto socket.

+7  A: 

recv does not place a null terminator at the end of the string (whilst printf %s assumes there is one).

You must use byteRead to determine the length of the string. Add a null terminator if you want to use a function like printf, but ensure your buffer has the space for it even on a maximum-size read.

Artelius
+1  A: 

Yes.

strlen() looks for the nearest NULL terminator, as in a conventional C string.

recv() has nothing to do with null terminator and would not add one. So, the strlen call is wrong and may even crash your program by unauthorized read.

Pavel Radzivilovsky
ok i got that point. But on server side, when client sends message to the server through socket, it receives correctly and i didn't add null pointer. Even thought i added null pointer before i send to the client, it still shows garbage things;
REALFREE
@REALFREE: When we say null terminator, we are talking about the "nul" *character*, not a null *pointer*. Also, in your server case it may *appear* to work because of good luck but you are doing something improper.
Artelius
+1  A: 

The problem here is that buffer is not NULL-terminated by recv(). In fact, recv only puts the raw socket data into the buffer. If it recieves 256 bytes of data, whatever comes after that might be null characters (e.g. as it is on your server) or it might be something else (as it is on your client). It's an artifact of program execution, not of how you programmed it.

The easiest and fastest way to fix this:

  1. Allocate buffer with size MAXBUF + 1. The +1 will be for an extra NULL character.
  2. Immediately before the printf, add a null character at buffer[bytesRead].

So all-told:

buffer = malloc((MAXBUF + 1) * sizeof(char));          // NEW

while((byteRead = recv(ssock, buffer, MAXBUF, 0)) > 0)
{
    if(byteRead <= 0)
        break;
    else {
        buffer[bytesRead] = '\0';                      // NEW
        printf("%s", buffer);
    }
}
Andres Jaan Tack