TCP/IP
- TCP/IP 模型:应用层、传输层、网络层、数据链路层(网络接口层)。
- 数据包结构:包首部 + 数据
TCP 三次握手
- 客户端将标志位 SYN(Synchronize sequence numbers) 置为 1,随机生成序列号(Sequence number)=A,发送数据包到服务端,客户端进入 SYN-SENT 状态
- 服务端收到数据包后由标志位 SYN=1 知道客户端请求建立连接,服务端将标志位 SYN 和 ACK(Acknowledgment) 都置为 1,随机生成序列号=B,设置 Acknowledgment number=A+1,发送数据包到客户端,服务端进入 SYN-RECEIVED 状态
- 客户端收到数据包后确认 ACK 是否为 1,并且 Acknowledgment number 是否为 A+1,正确那么客户端将标志位 ACK 置为 1,设置 Acknowledgment number=B+1,发送数据包到服务端,服务端确认 ACK 是否为 1,并且 Acknowledgment number 是否为 B+1,正确则连接建立成功,客户端和服务端进入 ESTABLISHED 状态
TCP 四次挥手
发起中断连接的可以是客户端,也可以是服务端。
- 主机 A 将标志位 FIN(Last packet from sender) 置为 1,发送数据包到主机 B,主机 A 进入 FIN-WAIT-1 状态,只接收数据,不再发送数据
- 主机 B 将标志位 ACK 置为 1,发送数据包到主机 A,表明确认接收请求,主机 B 进入 CLOSE-WAIT 状态,等待数据发送完成。主机 A 接收数据包进入 FIN-WAIT-2 状态。
- 主机 B 发送标志位 FIN 为 1 的数据包,确认数据发送完成,主机 B 进入 LAST-ACK 状态。
- 主机 A 将标志位 ACK 置为 1,发送数据包到主机 B,表明可以关闭连接,进入 TIME-WAIT 状态,在 2MSL(Maximum Segment Lifetime)期间如果主机 B 没接收到 ACK 数据包,可以重传,如果主机 B 正常关闭,那么等待期过后主机 A 进入 CLOSED 状态。主机 B 收到 ACK 数据包进入 CLOSED 状态。
参考
HTTP/2、HTTP/3
HTTP/2
采用二进制分帧。
相较于 HTTP/1.1 解决了应用层的队头阻塞,但是 TCP(传输层) 本身的队头阻塞依然存在。
特性:
- 多路复用(Multiplexing)
- 头部压缩(Header Compression)
- 请求优先级(Request Priorities)
- 服务端推送(Server Push)
HTTP/3
HTTP/3 使用 QUIC,一种基于 UDP 的多路复用传输协议。
HTTP/2 队头阻塞影响单条 TCP 上的所有传输,而 QUIC 协议下丢包只会影响数据包所在流。
特性:
- 减少了 TCP 三次握手及 TLS 握手时间
- 改进的拥塞控制
- 避免队头阻塞的多路复用
- 连接迁移
- 前向冗余纠错
参考
- en.wikipedia.org/wiki/HTTP/2
- en.wikipedia.org/wiki/HTTP/3
- 关于队头阻塞(Head-of-Line blocking),看这一篇就足够了
- 科普:QUIC 协议原理分析
TLS
TLS 1.2 需要 2-RTT(Round Trip Time)。
TLS 1.3 需要 1-RTT,相较于 TLS 1.2 不需要交换密钥。
参考
DNS
DNS(Domain Name System)根据域名查出 IP 地址。
CDN
CDN(Content Delivery Network)是指一組分布在不同地理位置的服务器,协同工作以提供网络资源的快速交付。
HTTP 请求方法
| 方法 | 描述 |
|---|---|
| GET | 请求指定资源 |
| HEAD | 类似于 GET 请求,但没有响应体 |
| POST | 提交数据到指定资源(创建) |
| PUT | 提交数据替换目标资源(替换) |
| DELETE | 删除指定资源(删除) |
| CONNECT | 略 |
| OPTIONS | 描述目标资源的通信选项,一般用于跨域预检 |
| TRACE | 略 |
| PATCH | 对资源进行部分修改(修改) |
HTTP 状态码
HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误(500–599)。
常见的 HTTP 状态码:
| 状态码 | 英文名称 | 中文描述 |
|---|---|---|
| 200 | OK | 请求成功 |
| 301 | Moved Permanently | 永久移动 |
| 302 | Found | 临时移动 |
| 304 | Not Modified | 未修改 |
| 401 | Unauthorized | 请求要求用户的身份认证 |
| 403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
| 404 | Not Found | 服务器无法根据客户端的请求找到资源 |
| 500 | Internal Server Error | 服务器内部错误,无法完成请求 |
跨域
浏览器有一个重要的安全策略,称之为同源策略。
协议+主机+端口相同是为同源,反之为跨域。
常见解决方案:
- JSONP(遗老)
- 正向代理,适用于生产环境不发生跨域,但开发环境发生跨域
- 跨源资源共享(CORS),设置
Access-Control-Allow-Origin
参考
HTTP 缓存
在规范里没有看到强缓存和协商缓存的概念,不过因为这俩概念被广泛应用,所以后面基于强缓存和协商缓存做解释。
强缓存
在 HTTP/1.0 中,由 Expires 判断资源是否过期。
在 HTTP/1.1 中,由 Cache-Control: max-age 判断资源是否过期,优先级高于 Expires。
如果命中缓存,那么复用资源,不会再向服务器发送请求。
协商缓存
Last-Modified/If-Modified-Since
服务器返回资源时会添加 Last-Modified 字段到响应头,表示资源最后修改时间。
当客户端请求资源时会添加 If-Modified-Since 字段到响应头,询问服务器自指定时间以来资源是否有更改。
如果命中缓存,那么服务器返回 304 Not Modified,否则返回 200 OK 和最新资源。
这种方式存在缺陷:
- 时间格式复杂且难以解析
- 分布式服务器难以同步文件更新时间
ETag/If-None-Match
优先级高于 Last-Modified/If-Modified-Since。
服务器返回资源时会添加 ETag 字段到响应头,这是服务器生成的随机字符串。
当客户端请求资源时会添加 If-None-Match 字段到响应头,询问服务器资源是否有更改。
如果命中缓存,那么服务器返回 304 Not Modified,否则返回 200 OK 和最新资源。
Cache-Control
max-age:资源有效期限,强缓存no-cache:每次请求资源需要验证是否过期,协商缓存no-store:禁用缓存private:私有缓存,例如只能被终端用户的浏览器缓存,不允许 CDN 等中间服务缓存public:共享缓存,可以被所有中间服务缓存
重新加载和强制重新加载
浏览器重新加载:
Cache-Control: max-age=0
浏览器强制重新加载:
Pragma: no-cache
Cache-Control: no-cache