HTTP响应连接重置?

4

我正在编写一个简单的Web服务器,实现了HTTP 1.1协议的一些组件。目前为止,我有一个TCP服务器,可以向所有收到的TCP连接提供静态网页服务。我觉得可能会存在竞争条件或其他我不知道的事件。

以下是相关代码的要点:

char hello[] =
    "HTTP/1.1 200 OK\r\n"
    // "Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT\r\n"
    // "Content-Length: 131\r\n"
    // "Connection: close\r\n"
    "\r\n"
    "<html>\n"
    "<head>\n"
    "  <title>An Example Page</title>\n"
    "</head>\n"
    "<body>\n"
    "  Hello World, this is a very simple HTML document.\n"
    "</body>\n"
    "</html>\n";

while(true) {
    addrlen = sizeof(peer);
    sockd2 = ::accept(_sockd, (sockaddr*)&peer, &addrlen);
    if (sockd2 == -1) {
        perror("Wrong connection");
        continue;
    }
    write(sockd2, hello, sizeof(hello));
    // close(sockd2);
}

我正在使用Google Chrome浏览器连接到localhost:8080,如上所述,页面加载得非常好。

如果我取消注释close调用和Connection: close行,则页面将无法加载,开发者控制台会显示Failed to load resource: net::ERR_CONNECTION_RESET

如果我同时取消注释其中的一个http头行,则可以正常加载。

发生了什么?

1个回答

4
这里没有“竞态条件”。这是一个网络错误。
问题在于你没有正确读取请求并终止响应。
当浏览器向你已经关闭的连接写入数据时,你的端口会发出TCP RST,即“连接重置”。
读取请求。你必须关闭套接字或发送内容长度头。
你需要阅读HTTP 1.1 RFC。它不像你想象的那么简单。

我没有完整阅读RFC,但是阅读了我认为相关的章节:4. HTTP消息5. 请求6. 响应8. 连接。我不太确定您所说的正确终止响应的含义,但现在我认为我遇到的竞争条件与在发送响应之前未读取连接有关。 - vmrob
我的意思是要么关闭连接,要么发送一个内容长度头部(或使用分块编码)。在HTTP 1.1中,必须以这些方式之一来界定响应。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接