6

在 CI 中有工作代码,但不知道它为什么工作,所以我开始重写它,这样我才能真正理解发生了什么。

到目前为止,一切都很好!我重写了,并且 90% 确定我理解现在发生的一切;然而,问题是我不知道如何将recv( databff) 接收到的数据块存储到我预先分配的缓冲区 ( htmlbff) 中。

考虑下面的代码(请注意,我把它剥离了很多,所以它只包括基础知识,例如没有内存重新分配或泄漏保护等......):

#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;           
}

所以(如果我做得对,并且事情按照我的想法进行)c是当前数据块的大小,并且q是到目前为止接收到的数据总量(每次循环重复时q递增)。c目前我正在使用q内存处理(以防有人想知道),但我相信它在解决这个问题时也有目的。

无论如何,我要问的问题是关于第二条评论的。如何htmlbff正确存储 recv 中的数据?

4

4 回答 4

5

用于memcpy()将数据复制(附加)到 ,htmlbff但您还需要确保不超过htmlbff. BUFFERSIZE要么在接收到字节时停止接收数据,要么realloc()用于扩展htmlbff以包含更多数据。

例如:

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;
    }
}
于 2012-08-24T15:50:44.327 回答
2

使用,memcpy并偏移htmlbff:q

memcpy(htmlbff + q, databff, c);

您可以类似地recv直接进入htmlbff

c = recv(sock, htmlbff + q, MAXDATASIZE, 0));

但是保留一个单独的缓冲区很好,并且根据您的完整代码,它可能会使事情更清晰。

确保添加检查,BUFFERSIZE以免复制超出htmlbff. 你提到你已经剥离了realloc处理,所以也许你已经在处理这个了。

您的常量名称有点令人困惑,在缓冲数据时我会用它BUFFERSIZE来指示每个的大小,即databff.

于 2012-08-24T15:48:10.153 回答
2

我要做的是将recv()数据直接放入htmlbff,除非您需要对其进行更多处理。

确保您的realloc() htmlbff时间i - q小于,MAXDATASIZE以便始终有空间容纳另一个recv()

然后你会打电话recv(sock, htmlbff + q, MAXDATASIZE, 0)

于 2012-08-24T15:51:23.750 回答
1

您需要继续重新分配/扩展缓冲区以适应所有数据(如果从套接字读取的数据超过 MAXDATASIZE)= 这样当 recv 将数据读入 databff 时,您的 htmlbff 可以在内存中增长,然后可以附加新的读取到你的整体 htmlbff。

q 和 c 就像光标一样,可以跟踪您在哪里以及您必须走多远。

memcpy(htmlbff+q, databff, c); //Do this in your whle loop to append the data
于 2012-08-24T15:51:09.513 回答