c-使用fork和dup的简单http通用服务器



我正在尝试编写一个非常基本的HTTP服务器。我想将服务器和服务分离为两个单独的可执行文件(类似于inetd)。

所以我有一个通用服务器,它派生一个服务并使用exec执行代码。主回路如下:

while(true) {
    int client_sock;
    if ((client_sock = accept(server_sock, (struct sockaddr *) NULL, NULL)) < 0) {
        return -1;
    } 
    pid_t pid = fork();
    if (pid == 0) {
        close(server_sock);
        close(0);
        dup(client_sock);
        close(1);
        dup(client_sock);
        execvp(argv[2], argv+2);
        return -1;
    } else if (pid < 0) {
       assert(false);
    }
    close(client_sock);
}

该服务在stdin上读取,在stdout上写入,并处理简单的http请求。当我使用nc连接到服务器时,一切似乎都很好。nc接收并显示预期的http回复。

然而,当我使用web浏览器连接到服务器时,浏览器告诉我服务器突然关闭了连接(我认为是ECONNRESET错误)。我确信我的服务处理了请求:我用strace检查了我的服务的执行情况,所有预期的"write(1,…)"都在那里,没有任何close(1)。更令人惊讶的是,有时网络浏览器会收到回复。

提供的代码中是否有任何错误?如果没有,是什么原因导致了问题?

我想问题不在于您显示的代码,而在于您执行的程序。一个典型的问题是客户端(即您的程序)不读取HTTP头,而是只写入数据并完成。在这种情况下,浏览器的文件描述符将关闭,而套接字缓冲区中仍有来自服务器的未处理数据。这导致服务器操作系统发送RST数据包,然后在浏览器中进行ECONNRESET。如果你很幸运,浏览器在得到RST之前就得到并呈现了响应,所以你有时会看到连接重置错误,有时不会。

最新更新