When using recv, I have always done something like this:
int len = 1000;
int n = 0;
char buf[1000];
while(n < len) {
n += recv(socket, buf + n, len - n, 0);
}
my logic being that if recv does not recieve the full data of len
bytes, I should only receive the rest of the bytes (len - n
) and should not overwrite the data that is already recieved (so I offset the beginner of the buffer to the end of already received content). This seems to work perfectly fine whenever I use it.
However, most if not all examples of recv that I see simply do something like follows:
int len = 1000;
int n = 0;
char buf[1000];
while(n < len) {
n += recv(socket, buf, len, 0);
}
Does this not leave you vulnerable to overwriting the beginning of your buffer if recv is called more than once?
Both of your examples are not accounting for the possibility of recv()
failing. You need to check the return value for errors, eg:
char buf[1000];
int len = sizeof(buf);
int n = 0, ret;
while (n < len) {
ret = recv(socket, buf + n, len - n, 0);
if (ret <= 0) {
// error handling...
break;
}
n += ret;
}
Your 1st example is good to use when you know up front exactly how many bytes you need to read, and can pre-allocate a buffer large enough to hold it all.
Your 2nd example is good to use when you need to stream the data more dynamically, 1 buffer at a time. For instance, maybe the data is being saved to a file. Or maybe the data is too large to fit in such a small buffer and needs to be processed in chunks. Or maybe the data is appended to another dynamically growing buffer for later use. Lots of reasons for this use-case, eg:
char buf[1000];
int n;
while (some condition) {
n = recv(socket, buf, sizeof(buf), 0);
if (n <= 0) {
// error handling...
break;
}
// use buf up to n bytes...
}