缓冲区未正确读取字符串

时间:2014-05-22 05:21:27

标签: c file sockets networking buffer

void download(char *file)
{
    int size = getsize(file);
    printf("Got size %d\n", size);
    sprintf(buff, "GET %s\n", file);
    send(sockfd, buff, strlen(buff), 0);
    rsize = recv(sockfd, buff, 1000, 0);
    sscanf(buff, "%d", &resultcode);
    printf("%s",  buff);
    if (strcmp(buff, "+OK\n") != 0)
    {
        printf("download failed\n");
    }
    FILE *dlfile = NULL;
    if ((dlfile = fopen(file, "r")) != NULL)
    {
        dlfile = fopen(file, "w");
        do
        {
            rsize = recv(sockfd, buff, 1000, 0);
            for (int i = 0; i < rsize; i++)
            {
                fprintf(dlfile, "%c", buff[i]);
            }
            size = size - rsize;
        } while (size != 0);
    }
    fclose(dlfile);
}

我正在尝试使下载功能打印出用户输入的文件内容,然后将其保存到当前目录中。我做了调试行printf("%s", buff);并打印出+OK\n(filename)。它应打印出+OK\n。它还打印出download failed然后打印segmentation fault错误。我错过了什么?

1 个答案:

答案 0 :(得分:0)

这里发生了几件事。首先,recv和send基本上对字节数组进行操作,因此它们不知道行结尾等。另请注意,recv不能保证填充缓冲区 - 它通常会读取缓冲区限制内可用的内容。对于你的strcmp&#34; + OK \ n&#34;,你可以使用长度为4的strncmp,但这有点直接(见下文)。接下来请注意,recv不会终止buff字符串,因此你的printf很容易崩溃。

当你进入循环时,缓冲区已经包含了其余I / O的一部分。可能包含其他字段或文件的一部分。你也需要处理它。我不清楚getize是做什么的 - 但是使用那个大小驱动你的循环似乎是不对的。此外,您对fprintf值的循环可以通过调用fwrite替换。

总的来说,您需要正确缓冲并解析传入的数据流。如果你想自己做,你可以查看fdopen获取FILE对象。