假设客户端有多个文件要通过 HTTP Post 方法发布到服务器,则会有两个 api 调用。因为我不想创建两个 TCP 连接并且想重用 TCP 连接,所以我在第一个请求中使用 Http keep-alive 标头,现在我只需要在第一个请求时建立一个 TCP 连接来发送多个文件
但是服务器如何区分这两个文件呢?当我们不使用keepalive时,客户端的操作系统会发送EOF标志(文件结束)来指示服务器文件已完成传输
以下是我的假设,不确定是否正确:
现在我们使用 keep-alive,因此服务器上的 EOF 不会关闭连接,因此可以通过同一连接发送第二个文件并以 EOF 结尾。但是当客户端不想再发送任何文件时如何关闭 TCP 连接呢?如果客户端发送另一个EOF,服务器可能会认为他要发送另一个文件?
我唯一能想到的是,假设你只有 5 个文件要发送,在第 5 个 HTTP 请求中,你不发送 keep-alive 标头,但第 1 个、第 2 个、第 3 个和第 4 个请求都需要发送对于 keep-alive 标头,我的理解正确吗?
不,事实并非如此。HTTP 请求的结束可以通过接收分隔空行(对于没有正文的请求)或通过读取请求的“Content-Length”标头中指定的确切字节数(对于具有固定长度正文的请求)来检测。 ),或者通过读取 0 字节块(对于分块请求)。
从另一个答案链接的 RFC 9112 详细讨论了消息框架,特别是第 6.3 节“消息正文长度”。
这是不正确的。TCP 没有其他方法来“发送 EOF 标志”,除了关闭发送方的连接(shutdown(SHUT_WR) 操作),这是最终的 – 无法在该方向发送更多数据,并且通常会导致另一个方向也关闭。
更一般地说,“EOF”不是一个实际的消息;而是一个消息。在编程语言中,它是由是否存在消息来确定的——从 read() 操作获得 0 字节结果后会引发 EOF。但 TCP 无法任意发出信号,因为它不向接收者报告消息边界;它实际上无法传递 0 字节消息。(事实上,空 TCP 段通常用作“保持活动”机制,特别是因为它们不会导致接收方看到 0 字节读取。)
(换句话说:您不会通过发出 EOF 信号来关闭 TCP 连接,而是通过关闭 TCP 连接来发出 EOF 信号。)
这就是 RFC 9112 使用术语“close”的原因,例如在“请求消息从不以闭分隔符[…]”而不是“EOF 分隔”中。
标
Connection: keep-alive
头在 HTTP/1.1 中是隐式的,即仅在 HTTP/1.0 中需要。在持久 HTTP/1 中,一个请求在另一个请求之后发送,并且响应以相同的顺序返回。HTTP/1 还明确定义了消息(请求、响应)的结束位置(内容长度、传输编码标头),因此正确实现 HTTP/1 的应用程序可以检测消息边界。具体技术细节参见标准