c++cpointersnetwork-programmingrecv

Do I need to offset a pointer when calling recv?


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?


Solution

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