fprintf结果不正确

时间:2018-05-29 12:15:39

标签: c sockets printf

在下面的代码中,我尝试从套接字read并将结果存储在一个文件中。

实际发生的是,我的客户端向我的服务器发送了一个file.html的GET请求。我的服务器找到该文件并将其内容写入套接字。最后,我的客户端从thread_fd读取内容并重新创建文件。

由于某种原因,重新创建的文件的内容比原始文件少。我把问题定位到最后的一些行,这是缺失的。当我在printf("%s", buffer)循环中使用while时,STDOUT中的所有内容似乎都很好,但fprintf对于81.000字节大小的文件错过了一些3.000字节。

#define MAXSIZE 1000

int bytes_read, thread_fd;
char buffer[MAXSIZE];
FILE* new_file;

memset(buffer, 0, MAXSIZE);
if((new_file = fopen(path, "wb+")) == NULL)
{
    printf("can not open file \n");
    exit(EXIT_FAILURE);
}
while ((bytes_read = read(thread_fd, buffer, MAXSIZE)) > 0)
{

    fprintf(new_file, "%s", buffer);
    if(bytes_read < MAXSIZE)
        break;
    memset(buffer, 0, MAXSIZE);
}

4 个答案:

答案 0 :(得分:1)

您从套接字读取的二进制数据可能包含也可能不包含\ 0字节。当你然后fprintf那个数据时,fprintf会在它遇到的第一个\ 0处停止。在你的情况下,这是完整文件的3000字节。如果您的文件不包含\ 0字节,则fprintf将继续打印ram内容,直到它出现段错误。

使用write()将数据写回文件并检查错误。不要忘记关闭()文件并检查错误。

答案 1 :(得分:0)

您的代码应该/看起来像:

int readfile(int thread_fd, char *path)
{
    unsigned int bytes_read;
    char buffer[MAXSIZE];
    int new_file;

    if ((new_file = open(path, _O_CREAT|_O_BINARY,_S_IWRITE)) == -1) return -1;

    while ((bytes_read = read(thread_fd, buffer, MAXSIZE)) > 0)
    {
        if (write(new_file, buffer, bytes_read)!= bytes_read) {
            close(new_file);
            return -2;
        }
    }
    close(new_file);
    return 0;
}

答案 2 :(得分:0)

您的代码可能会出现一些问题。

最可能的原因是:

if(bytes_read < MAXSIZE)
    break;

read返回小于请求的字节数时,这将结束循环。然而,这是完全正常的行为,并且可能发生例如。当read呼叫时没有足够的字节可用时(它毕竟是从网络套接字读取)。只要read返回值&gt;,就让循环继续。 0(假设套接字是阻塞套接字 - 如果没有,您还必须检查EAGAINEWOULDBLOCK)。

此外,如果您接收的文件包含二进制数据,那么使用fprintf"%s"写入目标文件不是一个好主意。一旦找到'\0'字节(这在二进制数据中并不罕见),它将立即停止写入。请改用fwrite

即使您正在接收文字(由html文件扩展名建议),使用fprintf"%s"仍然不是一个好主意,因为收到的数据赢了& #39; t '\0'终止。

答案 3 :(得分:0)

这很有用!

ps:我不知道我是不是应该这样做,因为我是新来的,但实际上没有理由去消极。任何问题都是一个好问题。如果你知道它就回答它。不要判断它。

#define MAXSIZE 1000

int bytes_read, thread_fd, new_file;
char buffer[MAXSIZE];

memset(buffer, 0, MAXSIZE);

if((new_file = open(path, O_RDONLY | O_WRONLY | O_CREAT)) < 0)
{
    printf("can not open file \n");
    exit(EXIT_FAILURE);
}
while ((bytes_read = read(thread_fd, buffer, MAXSIZE)) > 0)
    write(new_file, buffer, bytes_read);
close(new_file);