# http的一些值得记住的知识点
# TCP
和HTTP
的一些知识点
现代浏览器和服务器建立了一个
TCP
连接后是否会在一个HTTP
请求完成后断开?什么情况下会断开
在 HTTP/1.0
中,一个服务器在发送完一个 HTTP
响应后,会断开 TCP
链接。但是这样每次请求都会重新建立和断开 TCP
连接,代价过大。所以虽然标准中没有设定,某些服务器对 Connection: keep-alive
的 Header
进行了支持。意思是说,完成这个 HTTP
请求之后,不要断开 HTTP
请求使用的 TCP
连接。这样的好处是连接可以被重新使用,之后发送 HTTP
请求的时候不需要重新建立 TCP
连接,以及如果维持连接,那么 SSL
的开销也可以避免。
TIP
持久连接:既然维持 TCP
连接好处这么多,HTTP/1.1
就把 Connection
头写进标准,并且默认开启持久连接,除非请求中写明 Connection: close
,那么浏览器和服务器之间是会维持一段时间的 TCP
连接,不会一个请求结束就断掉。
一个
TCP
连接可以对应几个HTTP
请求
如果维持连接,一个 TCP
连接是可以发送多个 HTTP
请求的。
一个
TCP
连接中HTTP
请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)?
HTTP/1.1
存在一个问题,单个 TCP
连接在同一时刻只能处理一个请求,意思是说:两个请求的生命周期不能重叠,任意两个 HTTP
请求从开始到结束的时间在同一个 TCP
连接里不能重叠。虽然 HTTP/1.1
规范中规定了管线化来试图解决这个问题,但是这个功能在浏览器中默认是关闭的。
TIP
由于 HTTP/1.1
是个文本协议,同时返回的内容也并不能区分对应于哪个发送的请求,所以顺序必须维持一致。比如你向服务器发送了两个请求GET /query?q=A
和 GET /query?q=B
,服务器返回了两个结果,浏览器是没有办法根据响应结果来判断响应对应于哪一个请求的。
连接头阻塞:在建立起一个 TCP
连接之后,假设客户端在这个连接连续向服务器发送了几个请求。按照标准,服务器应该按照收到请求的顺序返回结果,假设服务器在处理首个请求时花费了大量时间,那么后面所有的请求都需要等着首个请求结束才能响应。所以现代浏览器默认是不开启 HTTP Pipelining(管线化)
的。
在 HTTP2
中由于 Multiplexing
特点的存在,多个 HTTP
请求可以在同一个 TCP
连接中并行进行。
所以在http1.1
时代浏览器提高页面加载效率就是通过:
- 维持和服务器已经建立的
TCP
连接,在同一个连接上顺序处理多个请求。 - 和服务器建立多个
tcp
连接。
为什么有的时候不需要重新建立
SSL
连接(https
下的)
TCP
连接有的时候会被浏览器和服务端维持一段时间。TCP
不需要重新建立,SSL
自然也会用之前的。
收到的
HTML
如果包含几十个图片标签,这些图片是以什么方式、什么顺序、建立了多少连接、使用什么协议被下载下来的呢?
如果图片都是 HTTPS
连接并且在同一个域名下,那么浏览器在 SSL
握手之后会和服务器商量能不能用 HTTP2
,如果能的话就使用 Multiplexing
功能在这个连接上进行多路传输。不过也未必会所有挂在这个域名的资源都会使用一个 TCP
连接去获取,但是可以确定的是 Multiplexing
很可能会被用到。
如果发现用不了 HTTP2
呢?或者用不了 HTTPS(现实中的
HTTP2
都是在 HTTPS
上实现的,所以也就是只能使用 HTTP/1.1
)。那浏览器就会在一个 HOST
上建立多个 TCP
连接,连接数量的最大限制取决于浏览器设置,这些连接会在空闲的时候被浏览器用来发送新的请求,如果所有的连接都正在发送请求呢?那其他的请求就只能等等了。
长连接是一种永久连接吗?
事实上,长连接并不是一种永久连接。在长连接建立后,如果有一段时间没有发出HTTP
请求,那么这个长连接就会断开。这个超时的时间可以在header
中设置。
← WebSocket https的工作原理 →