http keep-alive如何工作?

goo*_*ing 39 sockets http

Keep-alives被添加到HTTP中,基本上减少了为每个新请求快速创建和关闭套接字连接的巨大开销.以下是它在HTTP 1.0和1.1中如何工作的摘要:

HTTP 1.0 HTTP 1.0规范并没有真正深入研究Keep-Alive应该如何工作.基本上,支持Keep-Alive的浏览器会在请求中添加一个额外的标头:

连接:保持活动当服务器处理请求并生成响应时,它还会为响应添加一个标头:Connection:Keep-Alive完成此操作后,套接字连接不像以前一样关闭,但在发送后保持打开状态响应.当客户端发送另一个请求时,它会重用相同的连接.连接将继续重用,直到客户端或服务器确定对话结束,其中一个连接断开连接.

以上说明来自这里.但我不明白一件事

完成此操作后,套接字连接不像以前那样关闭,但在发送响应后保持打开状态.

据我所知,我们只是发送tcp数据包来发出请求和响应,这有什么socket connection帮助,它是如何工作的?我们仍然需要发送数据包,但它怎么能以某种方式建立持久连接?这看起来很不真实.

Rem*_*eau 61

建立新的TCP连接(DNS查找,TCP握手,SSL/TLS握手等)存在开销.如果没有保持活动状态,则每个HTTP请求都必须建立新的TCP连接,然后在发送/接收响应后关闭连接.保持活动允许将现有TCP连接重用于多个请求/响应,从而避免所有这些开销.这就是使连接"持久"的原因.

在HTTP 0.9和1.0中,默认情况下,服务器在向客户端发送响应后关闭其TCP连接的末尾.客户端必须在收到响应后关闭其TCP连接的末尾.在HTTP 1.0(但不是0.9)中,客户端可以通过Connection: keep-alive在请求中包含标头来明确要求服务器不要关闭其连接的结尾.如果服务器同意,则它Connection: keep-alive在响应中包含标头,并且不会关闭其连接的结尾.然后,客户端可以重新使用相同的TCP连接来发送其下一个请求.

在HTTP 1.1中,keep-alive是默认行为,除非客户端明确要求服务器通过Connection: close在其请求中包含标头来关闭连接,或者服务器决定Connection: close在其响应中包含标头.

  • 没有.但是,DNS,TCP和SSL本身并不是轻量级系统,每个系统都需要时间和资源来执行各自的步骤,然后才能执行下一个步骤.DNS必须先将主机名解析为IP地址,然后才能建立TCP连接.TCP必须执行三次握手才能在建立SSL会话之前建立新连接.SSL涉及多次握手,来回交换加密信息.在给定的客户端/服务器对之间执行这些步骤的次数越少,就可以发送和响应更快的HTTP请求. (14认同)
  • 谢谢。这就是我不太明白的,为什么TCP连接很难创建。除了“DNS 查找、TCP 握手、SSL/TLS 握手”之外还需要做什么? (2认同)
  • @TechnikEmpire:是的,它确实解释了该机制的工作原理.再仔细阅读一遍.如果您不同意,请随时发布您自己的答案. (2认同)
  • @TechnikEmpire:请阅读HTTP规范,特别是[RFC 2616第4.4节](http://tools.ietf.org/html/rfc2616#section-4.4).有几种方法可以在不关闭连接的情况下发出HTTP消息的结束信号.客户端必须分析服务器的响应头以找出实际使用的机制.如果你正在编写自己的代理,你必须要小心,不要搞砸它们.您不能盲目地按原样发送所有内容,您可能必须分析/调整HTTP消息,因为保持活动是基于每个连接处理的,并且代理有2个连接. (2认同)

JB *_*zet 21

我们来做个比喻吧.HTTP包括发送请求和获取响应.这类似于向某人询问问题并收到回复.

问题是问题和答案需要通过网络.要通过网络进行通信,请使用TCP(套接字).这类似于使用手机向某人提问并让此人回答.

当您加载包含2个图像的页面时,HTTP 1.0包含在

  • 打个电话
  • 请求页面
  • 得到页面
  • 结束通话
  • 打个电话
  • 要求第一张图片
  • 得到第一张图片
  • 结束通话
  • 打个电话
  • 要求第二张图片
  • 得到第二张图片
  • 结束通话

拨打电话并结束需要时间和资源.控制数据(如电话号码)必须通过网络传输.通过一个电话来获取页面和两个图像会更有效.这就是keep-alive允许做的事情.随着保持活力,以上变为

  • 打个电话
  • 请求页面
  • 得到页面
  • 要求第一张图片
  • 得到第一张图片
  • 要求第二张图片
  • 得到第二张图片
  • 结束通话


小智 12

这确实是网络问题,但毕竟这可能是合适的.

混淆源于面向分组和面向流的连接之间的区别.

Internet通常被称为"TCP/IP"网络.在低级别(IP,因特网协议),因特网是面向分组的.主机将数据包发送到其他主机.

但是,除了IP之外,我们还有TCP(传输控制协议).互联网这一层的全部目的是隐藏底层媒体的面向数据包的性质,并将两个主机(主机和端口,更准确)之间的连接呈现为数据流,类似于文件或管道.然后我们可以在OS API中打开一个套接字来表示该连接,我们可以将该套接字视为文件描述符(字面意思是Unix中的FD,非常类似于Windows中的文件HANDLE).

大多数其他Internet客户端 - 服务器协议(HTTP,Telnet,SSH,SMTP)都位于TCP之上.因此,客户端打开一个连接(套接字),将其请求(作为底层IP中的一个或多个口袋传输)写入套接字,从套接字读取响应(并且响应可以包含来自多个IP数据包的数据,如然后...然后选择是为下一个请求保持连接打开或关闭它.Pre-KeepAlive HTTP始终关闭连接.新客户端和服务器可以保持打开状态.

KeepAlive的优点是建立连接很昂贵.对于短请求和响应,它可能比实际数据交换需要更多的数据包.

轻微的缺点可能是服务器现在必须告诉客户端响应结束的位置.服务器不能简单地发送响应并关闭连接.它必须告诉客户:"读取20KB,这将是我的回复结束".因此,响应的大小必须由服务器预先知道并作为更高级协议的一部分(例如Content-Length:在HTTP中)传送给客户端.或者,服务器可以发送分隔符以指定响应的结束 - 这一切都取决于TCP之上的协议.

  • HTTP 有多种终止响应的方法,具体取决于响应的格式(普通、分块和 MIME)。`Content-Length` 并不总是使用/可能。 (2认同)
  • 我真的很喜欢这个答案,它并不是最适合这个问题,但你在答案中所写的正是我正在寻找的。为了使这不仅仅是感谢评论,是的,内容长度并不总是适用,但还有其他方法可以告诉客户端响应在哪里结束,这才是重要的,因为通过保持连接您将失去“阅读全部然后结束”的可能性打开。 (2认同)