Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store output of recv()?

In C I had working code but have no idea why it worked, so I started rewriting it so I could actually understand what is going on.

So far so good! I rewrote and am 90% sure I understand everything that is going on now; the issue however, is that I have no idea how to store the data chunk received by recv (databff) into my pre-allocated buffer (htmlbff).

Consider the following code (note that I stripped this down quite a bit, so it only includes the basics, e.g. no memory reallocation or leak protection, etc...):

#define BUFFERSIZE 4096
#define MAXDATASIZE 256

char *htmlbff, databff[MAXDATASIZE];
int c, i = BUFFERSIZE, q = 0;          
if(!(htmlbff = malloc(i)))
{
    printf("\nError! Memory allocation failed!");
    return 0x00;
}
while((c = recv(sock, databff, MAXDATASIZE, 0)) > 0)
{
     /*memory checks stripped out since they are irrelevent for this post*/
     /*store data to the appropriate area in htmlbff*/
     q += c;           
}

So (if I am doing this right, and things are going as I think they are) c is the size of the current data chunk, and q is the total amount of data received so far (q is incremented by c each time the loop repeats). At the moment I am using q for memory handling (in case anybody was wondering) but I believe that it will also have purpose in the solution to this problem.

At any rate the question I am asking is in regards to the second comment. How do I store the data from recv into htmlbff correctly?

like image 921
Keith Miller Avatar asked Aug 24 '12 15:08

Keith Miller


1 Answers

Use memcpy() to copy (append) data to the htmlbff but you also need to ensure you do not exceed the size of htmlbff. Either stop receving data when BUFFERSIZE bytes have been received or use realloc() to extend htmlbff to contain more data.

For example:

char* htmlbff;
size_t htmlbff_size = BUFFERSIZE;
htmlbff = malloc(htmlbff_size);

if (htmlbff)
{
    while((c = recv(sock, databff, MAXDATASIZE, 0)) > 0)
    {
        if (c + q > htmlbff_size)
        {
            htmlbff_size *= 2; /* Arbitrary doubling of size. */
            char* tmp = realloc(htmlbff, htmlbff_size);
            if (tmp)
            {
                htmlbff = tmp;
            }
            else
            {
                /* memory allocation failure. */
                free(htmlbff);
                htmlbff = 0;
                break;
            }
        }
        memcpy(htmlbff + q, databff, c);
        q += c;
    }
}
like image 128
hmjd Avatar answered Sep 19 '22 12:09

hmjd