您的位置:首页 > 理论基础 > 计算机网络

HTTP基础之连接管理

2016-08-01 18:59 162 查看
  1、Connection首部字段:允许发送端指定只与当前连接有关的选项。

  该字段有一个由逗号分隔的连接标签列表。3种不同类型的标签:

# 3种标签:HTTP首部字段名、close(本次事务结束后关闭此连接)、用作非标准选项的任意值
Connection: Meter, close, bill-my-credit-card
Meter: max-uses=3, max-refuses=6, dont-report


  HTTP应用程序在将报文转发给下一站之前(如代理),删除Connection首部以及Connection中列出的所有首部。将逐跳首部(只与一条特定连接有关,不能被转发的首部)名放入Connection首部被称为“对首部的保护”,可以防止无意中对本地首部的转发。此外,还有一些不能作为Connection首部值列出的逐跳首部:Proxy-Authenticate、Proxy-Connection和Transfer-Encoding和Upgrade等。

  至于为何要这么做,请参考下文的“哑代理/盲中继问题”。

  2、持久连接

  HTTP/1.1(以及HTTP/1.0的各种增强版本)允许HTTP设备在事务处理结束之后将TCP连接保持在打开状态,以便为未来的HTTP请求重用现有的连接。这种连接称为持久连接。非持久连接会在每个事务结束之后关闭。

  重用连接可以避免缓慢的连接建立阶段。而且已经打开的连接还可以避免慢启动的拥塞适应阶段,以便更快速地进行数据的传输。

  持久连接有两种类型:比较老的HTTP/1.0+ “keep-alive”连接,以及现代的HTTP/1.1 “persistent”连接。

  1)HTTP/1.0+ keep-alive连接

  这些早期的持久连接受到了一些互操作性设计方面问题的困扰,这些问题在后期的HTTP/1.1版本中都得到了修正,但很多客户端和服务器仍然在使用这些早期的keep-alive连接。

  (1)使用

  keep-alive已经不再使用了,而且在当前的HTTP/1.1规范中也没有对它的说明了。但浏览器和服务器对keep-alive握手的使用仍然相当广泛。

  客户端可以通过包含Connection: Keep-Alive首部请求将一条连接保持在打开状态。如果服务器同意,就在响应中包含相同的首部。如果响应中没有Connection: Keep-Alive首部,客户端就认为服务器不支持keep-alive,会在发回响应报文之后关闭连接。

  (2)选项

  Keep-Alive首部只是请求将连接保持在活跃状态。发出keep-alive请求之后,客户端和服务器并不一定会同意进行keep-alive会话。它们可以在任意时刻关闭空闲的keep-alive连接,并可随意限制keep-alive连接所处理事务的数量。

  可以用Keep-Alive首部中指定的、由逗号分隔的选项来调节keep-alive的行为:

Connection: Keep-Alive  # Keep-Alive首部只有在提供Connection: Keep-Alive时才能使用
Keep-Alive: max=5, timeout=120  # timeout:估计了服务器希望将连接保持在活跃状态的(空闲)时间。不是一个承诺值
# max:估计了服务器还希望为多少个事务保持此连接的活跃状态。不是一个承诺值


  另外,Keep-Alive首部还可支持任意未经处理的属性(主要用于诊断和调试),语法为name [=value]。

  (3)一些规则

  在HTTP/1.0中,keep-alive并不是默认使用的。客户端必须发送一个Connection: Keep-Alive请求首部来激活keep-alive连接。

  Connection: Keep-Alive首部必须随所有希望保持持久连接的报文一起发送。如果客户端没有发送Connection: Keep-Alive首部,服务器就会在那条请求之后关闭连接。

  客户端探明响应中没有Connection: Keep-Alive响应首部,就可以知道服务器发出响应之后是否会关闭连接了。

  (4)哑代理/盲中继问题

  如果代理不理解Connection首部,而且不知道在转发到下一站之前将该首部删除,则会出现问题。很多老的或简单的代理都是盲中继(blind relay),它们只是将字节从一个连接转发到另一个连接中去,不对Connection首部进行特殊的处理。

  假设有一个Web客户端正通过一个作为盲中继使用的哑代理与Web服务器进行对话:

  I、Web客户端向代理发送带有Connection: Keep-Alive首部的请求,之后等待响应,以确定对方是否同意使用keep-alive连接;

  II、哑代理收到请求,但它并不理解Connection首部和keep-alive,只是将报文一字不漏地转发给服务器;

  III、Web服务器收到带有Connection: Keep-Alive首部的请求时,会误以为代理希望进行keep-alive对话。于是它同意了,回送了一个Connection: Keep-Alive响应首部;

  IV、哑代理将响应报文转发给客户端。客户端于是认为代理同意进行keep-alive对话。所以,此时客户端和服务器都认为它们在与代理进行keep-alive对话,但代理却对keep-alive一无所知;

  V、由于代理不理解keep-alive,在完成一次事务之后,它分别(半)关闭了与客户端的连接和与服务器的连接。这样客户端发出的下一次请求就无法收到来自服务器的响应了。

  为避免这个问题,才引入上文提及的逐跳首部。

  (5)Proxy-Connection首部:解决(一个)盲中继带来的问题

  浏览器向代理发送Proxy-Connection首部,而不是Connection首部。如果代理是盲中继,它会将Proxy-Connection首部转发给Web服务器,服务器将忽略此首部,不会带来任何问题。如果是个聪明的代理(能理解持久连接的握手动作),就用Connection首部取代Proxy-Connection首部,再发送给服务器,以收到预期的效果。

  如果在哑代理的任意一侧还有一个聪明的代理,则盲中继问题又会再次出现了。

  2)HTTP/1.1持久连接

  HTTP/1.1逐渐停止了对keep-alive连接的支持,用持久(persistent)连接取代了它。两者的目的相同,但后者的工作机制更优一些。

  与HTTP/1.0+的keep-alive连接不同,HTTP/1.1持久连接在默认情况下是激活的。要在事务处理结束之后将连接关闭,HTTP/1.1应用程序必须向报文中显式地添加一个Connection: close首部。但是,客户端和服务器仍然可以随时关闭空闲的连接。不发送Connection: close并不意味着服务器承诺永远将连接保持在打开状态。

  (1)一些规则

  只有当连接上所有的报文都有正确的、自定义报文长度时——即实体主体部分的长度都和相应的Content-Length一致,或者是用分块传输编码方式编码的——连接才能持久保持。

  参考资料:

  《HTTP权威指南》

不断学习中。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: