阅读 15

http

HTTP/0.9 和早期的 HTTP/1.0 协议对 HTTP 请求处理是串行化的。假如一个页面包含 3
个样式文件,同属于一个协议、域名、端口。那么,浏览器一共需要发起四次请求,并且
每次只能打开一个 TCP 通道,在一个请求资源完成下载后,立刻断开该连接,再开启一
个新的连接去处理队列中的下一个请求。随着页面资源大小、数量的不断扩增,网络延迟
时间会不断堆积,用户会面对满屏空白,等待过长时间而失去耐心。

并行连接
为了提高网络的吞吐能力,改进后的 HTTP 协议允许客户端同时打开多个 TCP
连接,并行地请求多个资源,充分利用带宽。通常,每一个连接之间都会有一定延迟,但
请求的传输时间是重叠的,总体上时延要比串行连接低很多。考虑到每一个连接都会
消耗系统资源,并且服务器需要处理海量的用户并发请求,浏览器会对并发请求数量做
一定的限制。即使 RFC 并没有规定具体的限制数量,各浏览器厂商也都会有自己的标准

持久连接(长连接)
早期的 HTTP 协议对每个请求都占用一个独立的 TCP 连接,这无疑增加了 TCP
的建立连接开销、拥塞控制开销、释放连接开销,改进后的 HTTP/1.0 和
HTTP/1.1(默认)都支持了持久连接。如果一个请求完成后,不会立刻断开连接
,而是在一定的时
间内保持连接,以便快速处理即将到来的 HTTP 请求,复用同一个 TCP
通道,直到客户端心跳检测失败或服务器连接超时。这个特性可以通过 HTTp
首部 Connection: keep-alive 来激活,客户端也可以发送 Connection: close
来主动关闭连接。所以,我们看到,并行连接和持久连接这两种优化是相辅
相成的,并行连接使得首次加载页面可以同时打开多个 TCP 连接,而持久连接保证了
后续的请求复用已打开的 TCP 连接,这也是现代 Web 页面的普遍机制。

管道化连接
持久连接让我们可以重用连接来完成多次请求,但它必须满足 FIFO
的队列顺序,必须保证前一个请求成功到达服务器、处理成功并且收到服务器返回的首个
字节,才可以发起队列中下一个请求。HTTP 管道允许客户端在同一个 TCP
通道内连续发起多个请求,而不必等待响应,消除了往返延迟时间差。但现实情况由于
HTTP/1.x 协议的限制,不允许数据在一个链路上交错到达(IO
多路复用)。设想一种情况,客户端服务器端同时发送一个 HTML 和多个 CSS
请求,服务器并行处理所有请求,当所有的 CSS 请求处理完成并加入到缓冲队列,
却发现 HTML 请求处理遇到问题而无限被挂起,严重时甚至造成缓冲区溢出
这种情况就叫做队首阻塞。因此,这个方案在 HTTP/1.x 协议中并没有被采纳。



### 1.TCP有哪些手段保证可靠交付
1、将数据截断为合理的长度。
2、超时重发
3、对于收到的请求,给出确认响应
4、校验出包有错,丢弃报文段,不给出响应,TCP发送数据端,超时时会重发数据
TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传
输过程中的任何变化。 如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认
收到此报文段。 (希望发端超时并重发)
5、对失序数据进行重新排序,然后才交给应用层
6、对于重复数据,能够丢弃重复数据
既然IP数据报会发生重复,TCP的接收端必须丢弃重复的数据。
复制代码

juejin.im/post/684490…