IP 数据包包含有效负载,例如 HTTP 信息,而 HTTP 信息又包含 html 信息。IP 数据包被封装到 TCP 段中,TCP 段可检测网络传输中的问题、请求重新传输丢失的数据、重新排列无序数据并帮助最大限度地减少网络拥塞。实现此操作的方式是 TCP 接收方在收到数据时以 ack 消息进行响应。发送方维护数据包发送时的计时器,如果计时器在消息被确认之前到期,则重新传输数据包。
TCP 发送方发送其初始请求,而 TCP 接收方收到其最后一个段并重新排列数据,这个过程是否都在单个 TCP 连接中完成?还是每次传输和确认都需要多个 TCP 连接?
我之所以问这个问题,是因为 apache2 有一个名为 KeepAlive 的声明。我不太明白。如果设置为“On”,KeepAlive 将允许每个连接保持打开状态以处理来自同一客户端的多个请求。但是,在 TCP 接收方收到整个消息(可能是整个 html 文档)之前,每个连接不是都保持打开状态吗?
答案1
但是,在 TCP 接收方收到整个消息(可能是整个 html 文档)之前,每个连接不是都保持打开状态吗?
是的 - 但如果不使用 KeepAlive,文档发送后它将关闭。使用 KeepAlive,它将允许客户端发出下一个请求,而无需断开连接并建立另一个 TCP 连接。
如果有客户端请求两个项目,则在没有 KeepAlive 的情况下会发生以下情况:
- 客户端请求 TCP 连接
- 服务器接受 TCP 连接
- 客户端请求 URI
- 服务器响应 - 希望发送 URI 的完整内容
- 客户端断开连接
- 服务器关闭套接字
- 客户端请求 TCP 连接
- 服务器接受 TCP 连接
- 客户端请求第二个 URI
- 服务器响应 - 希望发送 URI 的完整内容
- 客户端断开连接
- 服务器关闭套接字
以下是同样的事情,但是使用了 KeepAlive:
- 客户端请求 TCP 连接
- 服务器接受 TCP 连接
- 客户端请求 URI
- 服务器响应 - 希望发送 URI 的完整内容
- 客户端请求第二个 URI
- 服务器响应 - 希望发送 URI 的完整内容
- 客户端断开连接
- 服务器关闭套接字
如您所见,在第二个示例中,拆除并建立新 TCP 连接的开销已消失。对于负载较重且页面包含大量 URI 的服务器,它可以显著减少开销。
答案2
当您访问一个页面时,需要下载多个元素。您有主页,但也有 CSS、JS、图像等。对于 HTTP/1.0,每个请求都需要一个连接:客户端启动连接,发送 HTTP 请求,服务器使用 HTTP 标头进行响应,然后是内容,然后关闭连接。对于要获取的每个项目,都需要重复此操作,需要多个 TCP 连接。
为了简化操作,HTTP/1.0 中有一个非官方扩展,称为 KeepAlive,启用后,服务器端在发送完响应后,会在一段时间内(例如 2 秒)保持连接打开。在此期间,支持 keepalive 的客户端可以在同一个 TCP 连接中发送第二个请求。然后是第三个请求,依此类推,直到达到一定限制。此扩展成为 HTTP/1.1 的标准,称为持久连接。要使用此功能,客户端需要在标头中明确请求它。
您在此处看到的 KeepAlive 设置将为 HTTP/1.0 启用 keepalive 或为 HTTP/1.1 禁用 keepalive(取决于您选择的选项)。基于此:http://httpd.apache.org/docs/2.2/mod/core.html#keepalive,默认情况下它对 HTTP/1.1 启用,对 HTTP/1.0 禁用。