HTTP/S/2 & WebSocket 阅读笔记
Opened this issue · 6 comments
阅读范围:
- 《图解 HTTP》
- 《Web 性能权威指南》
- 关于三次握手和四次挥手,面试官想听到怎样的回答?
- “三次握手,四次挥手”你真的懂吗?
- 深度解密HTTP通信细节
网络分层模型和TCP/IP协议族
协议的战争: osi、tcp/ip
TCP/IP 的分层管理
TCP/IP 协议族分为4层:应用层、传输层、网络层和数据链路层
作用:
- 应用层:决定了向用户提供应用服务时通信的活动,HTTP 协议也处于该层
- 传输层:对上层应用层,提供处于网络连接中的两台计算机之间的数据传输
- 网络层:又名网络互联层,用来处理在网络上流动的数据包
- 链路层:又名数据链路层、网络接口层,用来处理连接网络硬件部分(属于硬件范围)
OSI 是由国际标准化组织ISO提出的 Open System Interconnection Reference Model,它的layer 7如下:
两者关系图谱如下:
TCP
TCP/IP 也常被称为“因特网协议套件”,IP 即 Internet Protocol(因特网协议),负责联网主机之间的路由选择和寻址;TCP 即 Transmission Control Protocol(传输控制协议),负责在不可靠的传输信道之上提供可靠的抽象层。
三次握手和四次挥手
TCP 提供了一种可靠、面向连接、字节流、传输层的服务,采用三次握手建立一个连接,采用4次挥手来关闭一个连接。
TCP 可以看成是一种字节流,它会处理 IP 层或以下的层的丢包、重复以及错误问题。
三次握手:
- 客户端主动发出连接请求的报文段,报文头部 SYN 置为 1,序号 seq 设置为 x(随机序号,即 ISN),服务端是 SYN-RCVD 状态。服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的
- 根据接收到的数据报文,接收到 SYN 为 1 则表示请求建立连接,随后服务端在报文段发出 SYN+ACK(都为 1),确认号 ack Acknowledge numbe 为 x + 1,同时把确认报文段中的序号 seq 设置为 y,表明服务器发送数据的初始序列号为 y,客户端收到数据包。客户端得到的结论是:服务端的接收、发送能力正常。
- 客户端收到服务器端的报文段后,要对服务器端中的 SYN 进行确认(SYN = 1 表明是要建立连接),然后检查 ack 是否正确,即第一次发送的 seq + 1,同时检查 ACK 是否为 1。若正确,随后在确认报文段中把确认比特位 ACK 设置为 1,然后把确认号 ack 设置为 y+1,自身的序号 seq 设置 x+1。服务端接收到并确认 seq 值和 ACK = 1 后建立连接并置为 established 状态,得到的结论是:客户端的接收、发送能力正常。
三次握手的最终结论是:客户端和服务端都确认了各自以及对方的接收、发送能力是正常的。
四次挥手
参照上图,其流程与三次握手类似,差别是在服务端回包的时候,服务端发出的 FIN\ACK 是分开的。这是因为收到客户端发出的 FIN 包,服务端及时回应 ACK;服务端发 FIN 包要在所有数据响应完成后发出,所以 FIN\ACK 是分开的。
需要理解的几个概念
- SYN(synchronize),用于初如化一个连接的序列号
- ACK(acknowledgement)即确认号
- FIN,表示该报文段的发送方已经结束向对方发送数据(用于在链路正常情况下的正常单向终止与结束)
- RST 的设计用意在于链路发生意料之外的故障时告知链路上的各方释放资源(一般指的是NAT网关与收发两端)
- ISN(Initial Sequence Number)
三次握手的一个重要功能是客户端和服务端交换ISN,便于在对方接收收知道如何按序列号组装数据 - 序列号回绕
一个tcp流的初始序列号(ISN)并不是从0开始的,而是采用一定的随机算法产生的,因此ISN可能很大(如 2^32-10),因此同一个 tcp 流的 seq 号可能会回绕到 0。而 tcp 对于丢包和乱序等问题的判断都是依赖于序列号大小比较的。此时就出现了所谓的tcp序列号回绕(sequence wraparound)问题。通过_内核解决办法_来解决。
报文信息
字段 | 长度 | 含义 |
---|---|---|
Source Port | 16比特 | 源端口,标识哪个应用程序发送。 |
Destination Port | 16比特 | 目的端口,标识哪个应用程序接收。 |
Sequence Number | 32比特 | 序号字段。TCP链接中传输的数据流中每个字节都编上一个序号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号。 |
Acknowledgment Number | 32比特 | 确认号,是期望收到对方的下一个报文段的数据的第1个字节的序号,即上次已成功接收到的数据字节序号加1。只有ACK标识为1,此字段有效。 |
Data Offset | 4比特 | 数据偏移,即首部长度,指出TCP报文段的数据起始处距离TCP报文段的起始处有多远,以32比特(4字节)为计算单位。最多有60字节的首部,若无选项字段,正常为20字节。 |
Reserved | 6比特 | 保留,必须填0。 |
URG | 1比特 | 紧急指针有效标识。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。 |
ACK | 1比特 | 确认序号有效标识。只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。 |
PSH | 1比特 | 标识接收方应该尽快将这个报文段交给应用层。接收到PSH = 1的TCP报文段,应尽快的交付接收应用进程,而不再等待整个缓存都填满了后再向上交付。 |
RST | 1比特 | 重建连接标识。当RST=1时,表明TCP连接中出现严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立连接。 |
SYN | 1比特 | 同步序号标识,用来发起一个连接。SYN=1表示这是一个连接请求或连接接受请求。 |
FIN | 1比特 | 发端完成发送任务标识。用来释放一个连接。FIN=1表明此报文段的发送端的数据已经发送完毕,并要求释放连接。 |
Window | 16比特 | 窗口:TCP的流量控制,窗口起始于确认序号字段指明的值,这个值是接收端正期望接收的字节数。窗口最大为65535字节。 |
Checksum | 16比特 | 校验字段,包括TCP首部和TCP数据,是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。 |
Urgent Pointer | 16比特 | 紧急指针,只有当URG标志置1时紧急指针才有效。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。紧急指针指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。 |
Options | 可变 | 选项字段。TCP协议最初只规定了一种选项,即最长报文段长度(数据字段加上TCP首部),又称为MSS。MSS告诉对方TCP“我的缓存所能接收的报文段的数据字段的最大长度是MSS个字节”。 新的RFC规定有以下几种选型:选项表结束,无操作,最大报文段长度,窗口扩大因子,时间戳。
|
Padding | 可变 | 填充字段,用来补位,使整个首部长度是4字节的整数倍。 |
data | 可变 | TCP负载。 |
HTTP 协议
stateless
HTTP 是一种不保存状态,即无状态协议(stateless)。它自身不具备保存之前发送过的请求或响应的功能,为了实现保持状态的功能,引入了 Cookie 技术。
持久连接
最初每进行一次 HTTP 通信就要断开一次 TCP 连接;随着 HTTP 普及且传输数据越来越大,引入了持久连接(HTTP Persistent Connections,即 HTTP keep-alive 或 HTTP connection reuse)。特点是:只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。
管线化
在持久化连接的基础上,引入管道化方式发送请求,即可以同时并行发送多个请求,而不需要一个接一个等待响应。
https
http 有哪些不足:
- 通信使用明文(不加密),内容可能会被窃听
- 不验证通信方的身份,因此有可能会被伪造
- 无法证明报文的完整性,所以内容可能已被篡改
图文并茂介绍:
相关细节可以再阅读阮一峰老师的 SSL/TLS协议运行机制的概述
SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
WebSocket
WebSocket 由多个标准构成: WebSocket API 是 W3C 定义的,而 WebSocket 协议(RFC 6455)及其扩展则由 HyBi Working Group(IETF)定义。
WebSocket 可以实现客户端与服务器间双向、基于消息的文本或二进制数据传输。WebSocket 连接远远不是一个网络套接字,因为浏览器在这个简单的 API 之后隐藏了所有的复杂性,而且还提供了更多服务:
• 连接协商和同源策略;
• 与既有 HTTP 基础设施的互操作;
• 基于消息的通信和高效消息分帧;
• 子协议协商及可扩展能力。
WebSocket 是浏览器中最通用最灵活的一个传输机制,其极简的 API 可以让我们在客 户端和服务器之间以数据流的形式实现各种应用数据交换(包括 JSON 及自定义的 二进制消息格式),而且两端都可以随时向另一端发送数据。
不过,自定义数据交换协议的问题通常也在于自定义。因为应用必须考虑状态管理、 压缩、缓存及其他原来由浏览器提供的服务。设计限制和性能权衡始终会有,利用 WebSocket 也不例外。简单来说,WebSocket 并不能取代 HTTP、XHR 或 SSE,而为了追求最佳性能,关键还是要利用这些机制的长处。
http 2.0
HTTP2 采用二进制格式传输
取代了 HTTP1.x 的文本格式,二进制格式解析更高效。关键之一就是在应用层(HTTP/2)和传输层(TCP or UDP)之间增加一个二进制分帧层。
在二进制分帧层中, HTTP2 会将所有传输的信息分割为更小的消息和帧(frame),并对它们采用二进制格式的编码。
多路复用
代替了 HTTP1.x 的序列和阻塞机制,所有的相同域名请求都通过同一个 TCP 连接并发完成。在 HTTP1.x 中,并发多个请求需要多个 TCP 连接,浏览器为了控制资源会有 6-8 个 TCP 连接都限制。
HTTP2 中
- 同域名下所有通信都在单个连接上完成,消除了因多个 TCP 连接而带来的延时和内存消耗。
- 单个连接上可以并行交错的请求和响应,之间互不干扰
Header Compression
HTTP2 使用了专门为首部压缩而设计的 HPACK 算法。