在WireShark中观察以下场景:
我在这里看到的问题是,在从服务器(4090)接收到[FIN, ACK]并确认(4092)之后,http客户端尝试发送另一个HTTP请求,而不是立即closures(并且可能重新build立)TCP连接。 它看起来像[FIN, ACK]被HTTP客户端简单地忽略。
根据RFC 7230(6.3),HTTP协议使用Connection头指定了它的持久连接pipe理机制。 它工作得很好,因为它支持客户端和服务器。
但是HTTP通常运行在TCP之上。 TCP连接pipe理对协议不在意,可以独立于HTTP使用。 但是,HTTP客户端不支持处理这个(可能不应该,它应该在套接字级支持)。 但是服务器确实利用它,因为它允许在不发送额外的HTTP请求的情况下正常closures连接。 例如,当连接超时或configuration重载时,nginx发送FIN包。
注意当HTTP客户端从服务器接收到RST ,会closures连接。 它似乎是在套接字级别上完成的,因为在HTTP客户端的源代码中找不到与此相关的任何内容。
FIN消息,而服务器使用它,似乎是完全错误的。 RST在套接字级别上处理,但是FIN不是? PS我可以在Python 2/3中使用HTTP客户端,用C编写的Java和httperf实用程序来重现它。所以我认为HTTP客户端忽略FIN消息是很常见的。 我想明白为什么。