TCP 和 HTTP 连接管理不一致

TCP 和 HTTP 连接管理不一致

我在WireShark中观察到以下场景:

设想

我在这里看到的问题是,在[FIN, ACK]从服务器 (4090) 接收并确认 (4092) 后,http 客户端尝试发送另一个 HTTP 请求,而不是立即关闭 (并可能重新建立) TCP 连接。看起来它[FIN, ACK]只是被 HTTP 客户端忽略了。

根据 RFC 7230 (6.3),HTTP 协议规定了使用Connection标头进行持久连接管理的最佳机制。由于客户端和服务器都支持该机制,因此该机制运行良好。

然而,HTTP 通常在 TCP 之上运行。TCP 连接管理不知道顶层协议,可以独立于 HTTP 使用。但 HTTP 客户端不支持处理此问题(可能它们不应该支持,它应该在套接字级别上得到支持)。然而,服务器确实利用了它,因为它允许优雅地关闭连接而无需发送额外的 HTTP 请求。例如,FIN当连接超时或重新加载配置

注意:当 HTTP 客户端RST从服务器接收消息时,它会关闭连接。这似乎是在套接字级别完成的,因为我在 HTTP 客户端的源代码中找不到与此相关的任何内容。

  1. 我对情况的理解正确吗?FIN客户端忽略消息,而服务器使用它,似乎是完全错误的。
  2. 为什么RST是在套接字级别处理,但FIN事实并非如此?
  3. 是否有任何 RFC 或其他标准关于 HTTP 客户端应如何处理 TCP 连接关闭?
  4. 是 nginx 做了一些非标准的事情还是 HTTP 客户端不遵循标准?

PS 我能够使用 Python 2/3、Java 和httperf用 C 编写的实用程序中的 HTTP 客户端重现它。因此,我相信 HTTP 客户端忽略消息是很常见的FIN。我想了解原因。

相关内容