C - printf输出因后续代码而异

时间:2018-01-05 00:06:59

标签: c file sockets while-loop strcat

前言:我只是和C打交道,所以请原谅我的无能。这个问题的原因可能是基本的。

问题:我正在尝试读取文件并使用套接字通过http提供服务。出于某种原因,先前读取的文件的printf输出取决于包含的后续代码的数量。

这是我的代码。

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#include <netinet/in.h>


int main()
{

    // open a file to serve
    FILE *file;
    file = fopen("index.html", "r");
    if (file == NULL)
    {
        printf("Failed to open file.");
        exit(EXIT_FAILURE);
    }

    // Get file content
    char file_content[1024];
    if (fgets(file_content, 1024, file) != NULL)
    {

        fclose(file);

        // Add header to file content
        char http_header[2048] = "HTTP/1.1 200 OK\r\n\n";    
        strncat(http_header, file_content, 1028);

        // This output varies depending on inclusion of proceeding code.
        printf("%s", http_header);

        // create a socket
        int server_socket;
        server_socket = socket(AF_INET, SOCK_STREAM, 0);        

        // define the address
        struct sockaddr_in server_address;
        server_address.sin_family = AF_INET;
        server_address.sin_port = htons(8001);
        server_address.sin_addr.s_addr = INADDR_ANY;

        bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address));        
        listen(server_socket, 1);

        int client_socket;        
        while (1)
        {
            client_socket = accept(server_socket, NULL, NULL);
            send(client_socket, http_header, sizeof(http_header), 0);
            close(client_socket);
        }
        return 0;
    }

}

如果我注释掉printf语句之后的所有内容,我会得到这个预期的输出..

HTTP/1.1 200 OK

<html><body>Hi</body></html>

但是,如果我运行所有代码,我会得到这个......

HTTP/1.1 200 OK

如果我可以改进我的问题,请告诉我如何。谢谢。

1 个答案:

答案 0 :(得分:1)

Mark Benningfield和Yano帮助我理解了这个问题,非常感谢你们。

执行printf()时,不是直接进入终端窗口的字符串,每行都进入buffer

缓冲区中的每一行必须刷新才能在终端中显示。缓冲区可以由these events

自动刷新

\n结尾的字符串会自动刷新,这就是第一行HTTP/1.1 200 OK \r\n\n显示正常的原因。第二行<html><body>hi</body></html>不以\n结尾,或触发任何其他自动刷新事件,因此不会显示。

通常这不是问题,因为当程序终止时,缓冲区会自动刷新,并且通过printf进入缓冲区的所有行都会显示在终端中。由于我的底部程序进入无限循环,程序永远不会终止,缓冲区永远不会刷新。

fflush(stdout)强制写入printf的整个缓冲区后调用stdout

More info on fflush