一个 TCP 连接可以发多少个 HTTP 请求

5,647 阅读4分钟

  • 现代浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?

  • 一个 TCP 连接可以对应几个 HTTP 请求?

  • 一个 TCP 连接中 HTTP 请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)?

  • 为什么有的时候刷新页面不需要重新建立 SSL 连接?

  • 浏览器对同一 Host 建立 TCP 连接到数量有没有限制?

不着急,咱一个个来 ~~


第一个问题

现代浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?

解析:
请求头中 Connection 属性决定了连接是否持久。

HTTP/1.0 中 Connection 默认是 close 的,即每次请求都会重新建立和断开 TCP 连接;
HTTP/1.1 中 Connection 默认是 keep-alive 的,即tcp连接可以复用,不用每次都要重新建立和断开 TCP 连接。

一般情况下复用的 TCP连接在等待设置的超时时间之后还没有被任何连接使用的话,TCP 连接就会主动断开

答案:
默认情况下建立 TCP 连接不会断开,只有在请求报头中声明 Connection: close 才会在请求完成后关闭连接。


第二个问题

一个 TCP 连接可以对应几个 HTTP 请求?

答案:
从上一个问题可知,如果维持连接的话,一个 TCP 连接是可以发送多个 HTTP 请求的


第三个问题

一个 TCP 连接中 HTTP 请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)?

解析:
HTTP/1.1 存在一个问题,单个 TCP 连接在同一时刻只能处理一个请求,即两个请求的生命周期不能重叠,任意两个 HTTP 请求从开始到结束的时间在同一个 TCP 连接里不能重叠。
虽然 HTTP/1.1 规范中规定了 Pipelining 来试图解决这个问题,但是这个功能在浏览器中默认是关闭的。

Pipelining 在实践中会出现许多问题:

  • 一些代理服务器不能正确的处理 HTTP Pipelining
  • Head-of-line Blocking 连接头阻塞:在建立起一个 TCP 连接之后,假设客户端在这个连接连续向服务器发送多个请求。如果按照标准的话,服务器应该按照收到请求的顺序返回结果,假设服务器在处理首个请求时花费了大量时间,那么后面所有的请求都需要等着首个请求结束才能响应,造成了阻塞

基于 Pipelining 的两个问题,现代浏览器默认是不开启 HTTP Pipelining
HTTP2 提供了 Multiplexing 多路传输特性,可以在一个 TCP 连接中同时完成多个 HTTP 请求 !!!

答案:
HTTP/1.1 存在 Pipelining技术可以完成这个多个请求同时发送,但是由于浏览器默认关闭,所以可以认为这是不可行的。
HTTP2 中由于 Multiplexing 特点的存在,多个 HTTP 请求可以在同一个 TCP 连接中并行进行。


第四个问题

为什么有的时候刷新页面不需要重新建立 SSL 连接?

答案:
TCP 连接有的时候会被浏览器和服务端维持一段时间。TCP 不需要重新建立,SSL 自然也会用之前的。


第五个问题

浏览器对同一 Host 建立 TCP 连接到数量有没有限制?

答案:
有。Chrome 最多允许对同一个 Host 建立六个 TCP 连接,不同的浏览器有一些区别。


终章

若收到的 HTML 如果包含几十个图片标签,这些图片是以什么方式、什么顺序、建立了多少连接、使用什么协议被下载下来的呢?

1、 如果图片都是 HTTPS 连接并且在同一个域名下,那么浏览器在 SSL 握手之后会和服务器商量能不能用 HTTP2,如果能的话就使用 Multiplexing 功能在这个连接上进行多路传输。不过也未必会所有挂在这个域名的资源都会使用一个 TCP 连接去获取,但是可以确定的是 Multiplexing 很可能会被用到。

2、 如果发现用不了 HTTP2 呢?或者用不了 HTTPS(现实中的 HTTP2 都是在 HTTPS 上实现的,所以也就是只能使用 HTTP/1.1)。那浏览器就会在一个 HOST 上建立多个 TCP 连接,连接数量的最大限制取决于浏览器设置,这些连接会在空闲的时候被浏览器用来发送新的请求,若所有的连接都正在发送请求,那么其他的请求就只能等待。