Reputation: 1347
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?
Upvotes: 6
Views: 3034
Reputation: 59637
Use memcpy
, and offset htmlbff
by q
:
memcpy(htmlbff + q, databff, c);
You can similarly recv
directly into htmlbff
:
c = recv(sock, htmlbff + q, MAXDATASIZE, 0));
But it's fine to keep a separate buffer, and depending upon your full code, it may make things clearer.
Be sure that you add checks against BUFFERSIZE
so that you don't copy past the bounds of htmlbff
. You mentioned that you've stripped out realloc
handling, so maybe you're already handling this.
Your constant names are a bit confusing, when buffering data I would use BUFFERSIZE
to indicate the size of each chunk, i.e. the size of databff
.
Upvotes: 2
Reputation: 122001
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;
}
}
Upvotes: 5
Reputation: 54345
What I would do is recv()
data directly into htmlbff
, unless you need to do more processing on it.
Make sure that you realloc()
htmlbff
when i - q
is less than MAXDATASIZE
so that there is always room for another recv()
.
Then you would call recv(sock, htmlbff + q, MAXDATASIZE, 0)
Upvotes: 2
Reputation: 5973
You need to keep reallocating/expanding the buffer to fit all the data (if the data read off the socket exceeds MAXDATASIZE) = That way as recv reads data into the databff, your htmlbff can grow in memory and then the new read can be appended to your overall htmlbff.
q and c are like cursors to keep track of where you are up to and how far you have to go.
memcpy(htmlbff+q, databff, c); //Do this in your whle loop to append the data
Upvotes: 1