Home > Software engineering >  Do I need to offset a pointer when calling recv?
Do I need to offset a pointer when calling recv?

Time:10-29

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?

CodePudding user response:

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...
}

CodePudding user response:

it's all bad. if we're talking about C you need at least space for \0. you can remove it only when you're sure all is right. otherwise you couldn't test it. And all this stuff means you're not sure you can make it all in one hit so you may have say Transfer-Encoding: chunked there. If you don't

int btx;
....
char x[9001] = {0};
int b = 0;
int e = 0;
do
{
   b = recv(btx, x   e, 9000, 0);
   e = e   b;
}while(b != 0);

And C

std::stringstream fbtc_b;
int btx;
....
int b = 0;
do
{
   char x[9000];
   b = recv(btx, x, 9000, 0);
   fbtc_b.write(x, b);
}while(b != 0);
  • Related