如何存储recv()的输出?

时间:2012-08-24 15:43:55

标签: c sockets dynamic recv

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

到目前为止一切顺利!我重写了,并且90%确定我理解现在发生的一切;但问题是,我不知道如何将recvdatabff)收到的数据块存储到我预先分配的缓冲区(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是收到的数据总量far(q每次循环重复时递增c。目前我使用q进行内存处理(如果有人想知道),但我相信它也有解决这个问题的目的。

无论如何,我问的问题是关于第二条评论。如何正确地将来自recv的数据存储到htmlbff

4 个答案:

答案 0 :(得分: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;
    }
}

答案 1 :(得分:2)

使用memcpy,并htmlbff偏移q

memcpy(htmlbff + q, databff, c);

您同样可以recv直接进入htmlbff

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

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

请确保对BUFFERSIZE添加检查,这样就不会复制htmlbff的范围。你提到你已经剥离了realloc处理,所以也许你已经处理过了。

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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:1)

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

q和c就像游标一样,可以跟踪你的目标以及你需要走多远。

memcpy(htmlbff+q, databff, c); //Do this in your whle loop to append the data