使用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之前获得并呈现响应,因此您有时会看到连接重置错误,有时不会。