主题
网络协议
http协议发展过程
HTTP/0.91990年,HTTP/0.9 发布,支持GET请求,不支持POST请求。而且具有无状态性(丢失就找不回)HTTP/1.0- 新增了POST请求
- 新增请求头、 状态码等
- 新增cookie
HTTP/1.1- 新增keep-alive长连接
- 新增pipeline管道
- 新增PUT、 DELETE、 OPTIONS、 PATCH等新方法
HTTP/2.0- 头部支持二进制协议, 支持头部压缩
- 新增多路复用
http/1.1
- 长连接: 默认使用长连接,避免连接建立和释放的花销,但一个连接一次只能处理一个请求
- 管道传输: 支持管道传输(pipeline),可以不必等待请求响应就发起下一次请求,但响应结果必须保持请求出去的顺序,有一个响应卡住就会把后续请求卡住
- 并发连接: 对一个域名的请求允许分配多个长连接.(谷歌最多6个长连接)
- 请求方法: 新增PUT、 DELETE、 OPTIONS、 PATCH等新方法
- 缓存字段: 新增一些缓存字段(If-Modified-Since、 If-None-Match)
- 断点续传: 请求头引入Range字段
- 数据分块: 允许数据分块(chunked)利于大数据传输
http/2.0
2.0协议的请求标头
http
:authority cm.bilibili.com
:method POST
:path /cm/api/fees/pc
:scheme https- 二进制协议: 1.1版本的头部信息是文本,数据部分可以是文本也可以是二进制。2.0头部和数据都是二进制,统称为'帧'
- 多路复用: 废弃1.1的管道技术。同一个tcp连接中,可以同时发送多个请求和多个响应。并且不按照顺序。由于不按照顺序来处理响应,所以解决了http
队头堵塞问题 - 服务端主动推送: 允许服务端主动向客户端推送数据
http/3.0
解决了TCP的队头堵塞问题。TCP传输当中某些数据包丢失时,需要重新发送这些丢失的数据包,等到丢失的数据包到达对应的端点时才能被http处理。
- 使用
UDP协议,不需要三次握手,缩短建立连接的时间 - 解决了TCP队头堵塞问题
- 报文头和报文体分别进行认证和加密处理,保障安全性
- 实现动态可插拔
- 网络切换,连接平滑迁移
http状态码
| 状态码 | 英文描述 | 含义说明 |
|---|---|---|
| 1xx | 信息响应 | |
| 100 | Continue | 继续,客户端应继续其请求 |
| 101 | Switching Protocols | 协议切换,服务器根据客户端请求切换协议 |
| 2xx | 成功 | |
| 200 | OK | 请求成功 |
| 201 | Created | 已创建,请求成功并且服务器创建了新的资源 |
| 202 | Accepted | 已接受,服务器已接受请求,但尚未处理完成 |
| 204 | No Content | 请求成功,但响应报文不包含实体的主体部分 |
| 3xx | 重定向 | |
| 301 | Moved Permanently | 永久重定向,请求的资源已被永久移动到新位置 |
| 302 | Found | 临时重定向,请求的资源临时被移动到新位置 |
| 303 | See Other | 查看其他位置,通常用于 POST 请求的重定向 |
| 304 | Not Modified | 资源未修改,可使用缓存 |
| 307 | Temporary Redirect | 临时重定向,要求使用相同的请求方法重新请求新位置 |
| 308 | Permanent Redirect | 永久重定向,要求使用相同的请求方法请求新位置 |
| 4xx | 客户端错误 | |
| 400 | Bad Request | 错误请求,服务器无法理解请求语法 |
| 401 | Unauthorized | 未授权,需要身份验证 |
| 403 | Forbidden | 禁止访问,服务器拒绝请求 |
| 404 | Not Found | 未找到,请求的资源不存在 |
| 405 | Method Not Allowed | 方法不允许,服务器理解请求但拒绝使用此方法 |
| 408 | Request Timeout | 请求超时,服务器等待客户端发送请求时间过长 |
| 409 | Conflict | 请求冲突,服务器在完成请求时发生冲突 |
| 410 | Gone | 资源已删除,且不会再有 |
| 413 | Payload Too Large | 请求实体过大 |
| 414 | URI Too Long | 请求的 URI 太长 |
| 415 | Unsupported Media Type | 不支持的媒体类型 |
| 429 | Too Many Requests | 请求过多,被限制访问 |
| 5xx | 服务器错误 | |
| 500 | Internal Server Error | 服务器内部错误 |
| 501 | Not Implemented | 尚未实现,服务器不支持请求的功能 |
| 502 | Bad Gateway | 网关错误,服务器作为网关或代理时收到无效响应 |
| 503 | Service Unavailable | 服务不可用,服务器临时过载或维护 |
| 504 | Gateway Timeout | 网关超时 |
| 505 | HTTP Version Not Supported | 不支持的 HTTP 版本 |
什么是长连接
TCP 每次建立连接需要进行三次握手。如果采用短连接,每次收发数据前都要进行一次连接的建立和断开,开销较大。而开启长连接后,只需建立一次连接,就可以在这个连接上多次进行数据收发,从而避免频繁的握手和挥手过程,提高通信效率。
长连接与管道连接的区别
- 长连接是同步的,一次请求对应一次响应
- 管道连接是异步的,一次请求对应多个响应
网络分层
一、物理层
负责物理传输(比特流在节点间传输),把计算机连接起来的物理手段
作用: 传输0 1信号
设备: 网线、光纤
二、数据链路层
保证网络层和物理层的通信。在相邻的两台设备之间,把一堆 0 和 1(比特流)打包成有意义的数据帧(Frame),并且保证这些帧能正确送达(快递上门打包到驿站)
TIP
- 一帧: 64~1518字节
- 数据链路层就是负责“点对点”的可靠传输,它把原始的电/光信号(物理层)组织成有结构的数据帧,并在局域网范围内用 MAC 地址找到正确的设备,把数据交给上层的网络层继续处理
作用: MAC地址确认、ARP广播
设备: 交换机
三、网络层
负责决定数据从哪条路走,怎么跨越不同的“局域网”最终到达目标设备(快递员送到目标片区)
TIP
- 数据链路层只管同一个“网段”里的传输
- 网络层帮你跨网段、跨城市、跨运营商,把数据送到目标网络
作用: 分配IP地址
设备: 路由器
例子:
- 你在电脑浏览器输入 www.google.com:
- 你的电脑通过 DNS 找到 www.google.com 的 IP 地址(假设是 142.250.72.68)。
- 你的电脑把 HTTP 请求打包成 IP 包,目标地址就是 142.250.72.68。
- IP 包从你的电脑先到家里的路由器(同一网段)。
- 家用路由器根据路由表,把包转发给运营商。
- 运营商多次转发,最终到达 Google 的数据中心。
- Google 的服务器收到后返回 HTTP 响应,同样经过层层路由回到你这里。
四、传输层
把数据可靠地送到目标设备里的正确应用(软件)手上(快递员送货上门)
TIP
- 网络层只能保证“数据到这台电脑”
- 传输层要负责“数据准确无误地送到这台电脑上哪个应用”。
作用: 连接端到端TCP、UDP
设备: 操作系统内核
五、应用层
应用程序接收传输层数据,进行解读。HTTP、FTP、Telnet、SMTP、POP3等
总结
- 物理层: 就是还没打包、没贴单子的散装快递和运输通道(马路/铁路/光纤),负责提供传输介质和“基础运力”,但不管内容是什么。
- 数据链路层: 就是快递员上门把你的货装进快递箱,贴上寄件人和收件人的名字,送到最近的驿站/分拣中心,保证一栋楼内货品不丢、不串。
- 网络层: 就是快递公司把货物从你的小区驿站拉到对方城市的驿站,负责跨地区选路线、换车中转,确保货到了正确的城市和网点。
- 传输层: 就是对方城市的快递员把快递从驿站送到指定的收件人家门口,并且让对方签收确认,保证东西没丢、没乱序、没错人。
- 应用层: 就是用户只要在手机上填收发地址、打电话下单,或者开门收快递,完全不用关心快递公司中间是怎么送的、走了哪条路。
TCP
和UDP区别
| 特性 | TCP | UDP |
|---|---|---|
| 连接方式 | 面向连接,需要三次握手建立连接 | 无连接,直接发送数据 |
| 可靠性 | 可靠传输,保证数据无差错、不丢失、按序到达 | 不可靠传输,不保证到达顺序和完整性 |
| 传输方式 | 字节流,数据像连续的水流 | 数据报,独立的一个个数据包 |
| 传输速度 | 较慢,开销大(建立连接、确认、重传) | 较快,开销小 |
| 适用场景 | 文件传输、邮件、网页等对可靠性要求高 | 视频通话、语音、直播、游戏等实时性要求高 |
| 首部开销 | 较大(20 字节起) | 较小(8 字节) |
| 流量控制与拥塞 | 有流量控制和拥塞控制 | 无流量控制和拥塞控制 |
三次握手
在建立 TCP 连接前,客户端和服务器需要互相确认“我能发”“你能收”“你能发”“我能收”,三次交互确认没问题后,才正式建立连接。
TIP
- seq=x → 我发的“第一块数据”编号是 x
- SYN=1 → 我想建立连接
- ack=x → 我收到你编号为 x 的数据了
三次的作用:
- 你知道自己发得出去,对方能收到(客户端 → 服务器)SYN=1, seq=x
- 对方知道自己发得出去,你也能收到(服务器 → 客户端)SYN=1, ACK=1, seq=y, ack=x+1
- 网络上路径双向打通、状态同步,连接正式建立(客户端 → 服务器)ACK=1, seq=x+1, ack=y+1
客户端 服务器
| |
| -- 1. SYN, seq=x ------------------> |
| 我想建立连接,序列号 x |
| |
| <-- 2. SYN+ACK, seq=y, ack=x+1 ----- |
| 我也想建立连接,序列号 y |
| 收到你的 seq=x,确认号 ack=x+1 |
| |
| -- 3. ACK, seq=x+1, ack=y+1 -------> |
| 收到你的 seq=y,确认号 ack=y+1 |
| 连接建立完成 |
| |四次挥手
TIP
如何优雅的断开连接
- TCP双向通信,双方都能发送数据
- 当断开时,需要双方都同意并各自说清楚自己不再发数据
- 需要四次确认,不是一句拜拜就完事
步骤:
- 第一次挥手: 发送一个FIN完成包,表示不再发送数据,但还可以继续接收数据(我这边没有可说的,可以挂了,但是你可以继续说)
- 第二次挥手: 接收方收到FIN包,返回一个ACK确认包,表示我已收到你的FIN包(我知道你不说了,但是我这边还要在说几句)
- 第三次挥手: 服务器发送FIN完成包,表示不再发送数据(说完可以准备挂了)
- 第四次挥手: 客户端发送ACK确认包,收到你的FIN完成包,确认后进入 TIME_WAIT 等待一段时间再彻底断开(再见)
MSL是什么? 为什么断开要等待2MSL?
一个 TCP 报文在网络中可能存在的最长时间(网络上一个旧包最多能活多久)
TIP
等待 2 × MSL 是为了确保对方收到最后的 ACK,防止重传乱套
同时确保网络中残留的旧包都死干净,避免干扰新连接
滑动窗口
TCP 滑动窗口是一种
流量控制机制,让发送方一次能发多条消息,不用每发一条就等确认,但又能保证不把接收方撑爆。
理解:
小李往小王家发送包裹,小王家门口快递柜最多只能放3个包裹。 于是就双方约定一次最多寄3个包裹,只要总数不超过 3 个,寄出一个不用等待确认可以继续寄。 小王每收到一次就打个电话(ack)确认,这个包裹收到了,于是你窗口就向前滑动一格可以再多寄出一个。 这样保证高效率不断流,也保证不丢包不乱序
拥塞控制
TCP 拥塞控制是一种基于网络状态动态调整发送端数据发送速率的机制,旨在防止过多的数据注入网络,从而避免网络发生拥塞和性能下降。
- 慢开始: 初始发送窗口较小,每收到一个确认 (ACK),发送窗口成倍增长(试探网络)
- 拥塞避免: 拥塞窗口初始值为 1 个字节,当收到 ACK 后,加大发送量
- 拥塞发生窗口: 当收到超时 ACK 时,减少发送量
- 快重传: 当收到 3 个连续的 ACK 时,认为报文丢失,重发报文段
- 快恢复: 慢慢加大发送量
加密过程
- 对称加密: 既能加密又能解密
- 非对称加密: 分为公钥加密,私钥解密
浏览器的强缓存和协商缓存
缓存就是浏览器记住以前拿到过的资源,减少重复下载
INFO
- 强缓存: 直接使用缓存
- 协商缓存: 先问问服务器有没有更新,再决定是否使用
1. 怎么查看是否使用什么缓存?
答: 控制台响应标头包含cache-control: max-age=xxx就是命中强缓存;如果包含etag、last-modified就是命中了协商缓存
强缓存
通过
Expires和Cache-Control控制缓存存在本地的有效期
Expires: http/1.0推出的响应头,设置缓存的过期时间,由服务器返回,如果在有效期之内则直接读取缓存,修改了时间则造成缓存失效Cache-Control: http/1.1推出的响应头,相对时间,优先级高于Expires- max-age: 设置缓存的过期时间,单位秒
- no-cache: 先验证再决定用缓存,304 使用缓存,200 更新缓存
- no-store: 绝对不缓存
协商缓存
利用
Last-Modified、If-Modified-Since和Etag、If-None-Match这两对实现
INFO
- Last-Modified精度只能到秒,但是性能更好
- Etag精度可以到毫秒,但是性能更差,因为每次都要重新计算hash值
网络攻击
XSS
跨站攻击脚本。往网站当中注入恶意脚本,用户访问网站的时候就会被脚本劫持跳转、伪造表单提交、偷Cookie
如何防范?
- 输入过滤: 对用户输入的数据进行过滤、符号转义
- 加入安全策略: HTTP响应头加入安全策略,如:Content-Security-Policy(限制脚本来源,只允许白名单域名加载脚本)
- 富文本只允许安全标签
- URL参数过滤: Webview中的参数也会被注入,Webview中的URL需要添加白名单。(
?name<script></script>)
CSRF
跨站伪造请求。攻击者利用网站用户在登录状态下,向网站发送恶意请求,从而实现对受信任用户的操作。
如何防范?
- 使用token
- 验证来源: 服务端验证请求头
Origin和Referer,只允许信任域名的请求 - 避免敏感操作使用get请求