一个TCP连接可以发送多少个HTTP请求
- TCP连接是否会在一个请求结束后就断开连接?
在 HTTP 1.0 中一个服务器在发送完一个 HTTP 响应后会断开 TCP 连接,这样的话,每次请求都会重新建立和断开 TCP 连接,代价就会很大,所以虽然 HTTP 标准中没有设定,但是某些服务器在 header 中对 connection:keep-alive 进行支持,意思就是完成这个 HTTP 请求之后不要断开 HTTP 请求使用的 TCP 连接。这样的好处是连接可以被重复使用,之后发送 HTTP 请求的时候不需要再重新建立连接。
另外,如果维持连接,SSL 的重复开销也可以避免,既然维持 TCP 连接好处这么多,所以 HTTP 1.1 就把 connection 头写进标准,并且默认开启持久连接,除非请求头中写明 connection:close ,不然浏览器和服务器之间是会维持一段时间的 TCP 连接,不会一个请求结束就断开连接,所以这个问题的答案是:
默认情况下建立 TCP 连接不会断开,只有在请求头中声明 connection:close ,才会在请求完成之后断开连接
- 一个 TCP 连接可以发送多少个 HTTP 请求?
参考上面问题的答案,如果维持一个 TCP 连接是可以发送多个 HTTP 请求的
- 一个TCP 连接中的多个 HTTP 请求可以一起发送吗?
HTTP 1.1 存在一个问题,单个 TCP 连接在同一时刻只能处理一个请求,意思就是说请求的声明周期不能重叠,任意两个 HTTP 请求从开始到结束的时间在同一个 TCP 连接里不能重叠,HTTP 1.1 规范中规定了流水线 Pipelining 来试图解决这个问题,但是这个功能在浏览器中默认是关闭的。
这里解释一下什么是流水线:就是一个支持持久连接的客户端可以在一个连接中发送多个请求,收到请求的服务器必须按照请求收到的顺序来发送响应,至于标准为什么这么设定,我们可以大概推测一个原因——由于 HTTP 1.1 是个文本协议,同时返回的内容也并不能区分对应哪个发送的请求,所以顺序必须维持一致。比如你向服务器发送了两个查询请求,服务器返回了两个结果,浏览器是没有办法根据响应结果来判断哪个响应对应于哪一个请求的。
流水线这种设想看起来比较美好,但是在实践中会出现许多问题,一些代理服务器不能正确地处理 HTTP 流水线,正确地流水线实现是复杂的,在建立起一个 TCP 连接之后,假设客户端在这个连续向服务器发送了几个请求,按照标准,服务器应该按照服务器收到请求的顺序返回结果,假设服务器在处理首个请求时花费了大量的时间,那么后面所有的请求都需要等到首个请求结束后才能响应,所以现代浏览器默认是不开启 HTTP 流水线的。
但是 HTTP 2 提供了多路传输特性 Multiplexing,可以在同一个 TCP 连接中完成多个 HTTP 请求,所以这个问题的答案是:
在 HTTP 1.1 存在流水线技术,可以完成多个请求同时发送,但是由于浏览器默认是关闭的,所以可以认为这是不可行的。
在 HTTP 2 中由于多路传输特性的存在,多个 HTTP 请求可以在同一个 TCP 连接中并行发送。
那么在 HTTP 1.1 时代,浏览器是如何提高页面加载效率的呢?
首先维持和服务器已经建立的 TCP 连接,在同一个连接上,顺序处理多个请求;其次和服务器建立多个 TCP 连接。
- 为什么有的时候刷新页面不需要重新建立 SSL ?
因为 TCP 连接有的时候会被浏览器和服务器维持一段时间,TCP 不需要重新建立,那 SSL 自然也会使用之前的
- 客户端对同一个 host 建立的 TCP 连接数有没有限制?
假设我们还处在 HTTP 1.1 时代,那个时候还没有多路传输,当浏览器拿到一个有几十张图片的网页该怎么办呢? 肯定不能只开一个 TCP 连接顺序下载,那样用户肯定会等得很难受,但是如果每个图片都要开一个 TCP 连接的话,那电脑或者服务器肯定受不了,要是有1000张图片的话,总不能开1000个 TCP 连接吧。(端口上限65535) 所以这个问题的答案是有数量限制,不同的浏览器有一些区别,像 Chrome 浏览器最多允许对同一个 host 建立6个 TCP 连接
- 总结
现在我们回到最开始的问题,收到的 HTML 页面如果包含几十个图片标签,这些图片是以什么方式、什么顺序建立了多少连接、使用什么协议被下载下来的呢? 如果图片都是 HTTPS 连接,并且在同一个域名下,那么浏览器在 SSL 握手之后会和服务器协商能不能用 HTTP 2 ,如果能的话就会使用多路传输特性,在这个连接上进行多路传输;不过也未必会所有挂在这个域名下的资源都会使用同一个 TCP 连接去获取,但是可以确定的是多路传输特性很可能会被用到。 如果发现用不了 HTTP 2 或者 用不了 HTTPS (因为现实中的 HTTP 2 都是基于 HTTPS 实现的),所以也就只能使用 HTTP 1.1,那浏览器就会在一个 host 上建立多个 TCP 连接,连接数量的最大限制取决于浏览器的设置,这些连接会在空闲的时候被浏览器用来发送新的请求;如果所有的连接都正在发送请求的话,那其他的请求就只能等待了