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.
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.
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:
- Allocate
buffer
with sizeMAXBUF + 1
. The +1 will be for an extra NULL character. - Immediately before the
printf
, add a null character atbuffer[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);
}
}
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.
精彩评论