• HTTP协议学习笔记---HTTP持久连接和如何正确地关闭HTTP连接


    一,持久连接

    什么是持久连接?对于HTTP协议而言,它是基于请求响应模型,Client向Server发请求时,先建立一条HTTP连接,Server给Client响应数据后,连接关闭。

    当Client发送下一个请求时,需要重新再建立HTTP连接,这种方式就是:一个请求响应需要占用一条HTTP连接。而持久连接就是:只需要建立一条连接,然后在这条连接上 传输多个请求和响应。

    与持久连接相关的字段

    HTTP1.0中有一个Connection首部字段,它是一个逐跳首部字段。Connection:Keep-Alive,表示希望将此条连接作为持久连接。

    HTTP1.1中,建立的HTTP请求默认是持久连接的。当Client确定不再需要向Server发送数据时,它可以关闭连接,即在发送首部中添加Connection:Closed字段。

    二,如何提高HTTP请求的处理速度

    ①并行连接

    Client一次向Server请求建立多个HTTP连接,每个HTTP连接上发一个请求,这样就可以并行地发多个请求获取响应数据。

    比如,访问某个web页面,它上面有4幅图片,这些图片存储在不同的服务器上。那可以同时向服务器发4个HTTP请求去获取这四幅图片,而不是串行地依次发HTTP请求先获得第一幅图片,然后再发第二个HTTP请求获得第二幅图片....

    并行连接,显然增加了服务器端的压力,要求服务器能够承载大量的HTTP请求。

    ②持久连接

    持久连接的一个最大的好处是:大大减少了连接的建立以及关闭时延。

    HTTP连接是建立在TCP协议之上的,建立一条TCP连接需要三次握手,TCP连接关闭时需要四次挥手。这些都是需要时间的。

    而在第一点中提到:持久连接就是:只需要建立一条连接,然后在这条连接上 传输多个请求和响应。那么,就不需要频繁地建立连接,当前也就消除了连接建立以及关闭的时延了。

    如图:多个请求响应在一条连接内完成了。但是,这里也看出一个“缺点”,请求响应是顺序执行的。只有在请求1的响应收到之后,才会发送请求2,这就是持久连接与管道化连接不同的地方。

    ③管道化连接

    什么是管道化连接?

    显然,管道化连接是需要持久连接支持的。管道化连接是在持久连接的基础上,以“流水线”的方式发送请求:不需要等到请求1的响应到达Client,就可以发送请求2....

    HTTP连接如何正确地关闭?

    HTTP连接的关闭需要注意这两个问题:HTTP连接是双向的;HTTP请求的幂等性。

    连接是双向的

    TCP连接是双向的,TCP连接的发送端和接收端都分别有:发送缓冲区和接收缓冲区,它们对应着输出信道和输入信道。

    在JAVA中,JDK类库  java.net.Socket 类的 close()方法会关闭整个TCP连接,即输入信道和输出信道都被关闭了。

    另外,Socket类还提供了两个方法:shutdownInput() 和 shutdownOutput(),前者用来关闭输入信道,后者用来关闭输出信道。

    若只关闭其中TCP连接中的一条信道,则称之为半关闭。

    一般而言,关闭连接的输出信道总是安全的。当你确定 以后都没有数据要发送到对方时,你可以把你的输出信道关闭了。

    关闭输入信道有风险,可能会导致:连接被对端重置。

    比如,在 服务器刚好把输入信道关闭时,客户端向服务器发起了请求,那此时客户端就会收到一条“连接被重置”的报文。在这种情况下,客户端的操作系统就会把客户端中的接收缓冲区里面的数据都清空。如果,此时客户端的应用程序还未来得及从接收缓冲区中取走数据,那么以前发送请求获得的数据也都被清空了!

    因此, 正确的关闭HTTP连接的方式是:(以Client的视角来描述)

    Client先关闭自己的输出信道(Client不能把自己的输入信道关闭了)。

    然后Client周期性地轮询自己的输入信道的状态(比如,读取数据时,是不是 已经读到的 流的结尾了),如果读到了 流的结束标识符,那意味着Server发过来的数据都已经收到了。

    总之,对于HTTP连接的双方而言,当不再需要传输数据时,双方都先把自己的输出信道关闭了,然后读取输入信道中的流,如果读到了末尾(比如流结束符返回-1),那么就可以正常关闭HTTP连接了。

    参考资料:

    《HTTP权威指南》第四章

    《图解HTTP》

  • 相关阅读:
    csuoj 1391: Boiling Vegetables
    csuoj 1392: Number Trick
    nyist 78 圈水池
    1393: Robert Hood 旋转卡壳 凸包
    模板 旋转卡壳 凸包
    模板 凸包 旋转卡壳
    ASP.NET Web API2返回值处理流程
    DependencyInjection源码解读之ServiceProvider
    深入研究EF Core AddDbContext 引起的内存泄露的原因
    私有云方案——利用阿里云云解析实现DDNS
  • 原文地址:https://www.cnblogs.com/hapjin/p/5815368.html
Copyright © 2020-2023  润新知