零、四层模型
网络的基本单元是数据包,数据包在路由之间逐跳传递。
数据包的组成
数据包 = data + http header + tcp header + ip header
四层模型各自的作用和常见协议
应用层:指定数据的格式。(HTTP、DNS、TLS)
传输层:可靠地传输数据,并解决网络拥塞。(TCP、UDP、ICMP)
网络层:路由寻址。(IP)
链路层:在物理层传输数据。
一、应用层(Application)
对协议主要思考版本和报文头部。
0.HTTP 简史
HTTP 0.9:(一行协议启动万维网)
- 请求只有一行:get方法和路径。
- 返回只有HTML文档。
HTTP 1.0:(扩展内容)
- 增加了请求头、响应头、支持更多的文件类型、请求方法等等。
HTTP 1.1:(官方标准)
- 增加keep-alive,TCP连接默认不关闭,可以被多个请求复用。(避免每次重新三次握手和慢启动)
- 增加cache-control控制缓存。
HTTP 2.0:(提升性能)
- 二进制分帧
- 多路复用
- 首部压缩
- 服务端推送
1.HTTP
HTTP(Hyper Text Transfer Protocol)协议是一个无状态的请求-响应协议。
无状态:不保存状态,方便规模化(scalability)。
请求-应答:客户端发送一个请求,服务端返回一个响应。
报文结构
- 起始行:方法 + 路径 + 协议版本(请求) | 协议版本 + 状态码 + 原因(响应)
- 头部:一些键值对
- 空行:空行
- 实体:数据
HTTP 请求方法
- GET:获取资源
- POST:提交数据
- PUT:修改数据
- DELETE:删除资源
- HEAD:获取资源的头部
- OPTIONS:获取资源支持的选项
- CONNECT:建立连接,用于代理服务器
- TRACE:追踪请求-响应的路径
HTTP 状态码
- 100 Continue:请求中
- 200 OK:成功,并返回数据
- 204 No Content:成功,无内容
- 301 Moved Permanently:永久重定向
- 302 Found:临时重定向
- 304 Not Modified:使用协商缓存
- 400 Bad Request:请求语法错误
- 401 Unauthorized:没有登陆
- 403 Forbidden:没有权限
- 404 Not Found:资源不存在
- 418 I'm a teapot:服务器是茶壶,拒绝冲咖啡(愚人节彩蛋)
- 500 Internal Server Error:服务器错误
- 503 Service Unavailable:服务器不可用(如过载或维护)
HTTP 报文头部
- accept: text/html(客户端接受的文件类型。q是质量因子,代表权重)
- accept-encoding:gzip, deflate, br(客户端接受的压缩方式)
- accept-language:h-CN,zh;q=0.9(客户端接受的语言)
- content-encoding:gzip(压缩方式)
- content-type:text/html; charset=utf-8(文件类型)
- connection: Keep-Alive (请求结束后,是否关闭连接)
- cookie: session-id=12345 (携带cookie)
- set-cookie: session-id=12345 (设置cookie)
- expires: Wed, 22 Nov 2019 08:41:00 GMT (强缓存,绝对时间)
- cache-control: max-age=3600 (强缓存,相对时间)
- last-modified: Thu, 28 Oct 2021 08:58:07 GMT (协商缓存,最后修改时间)
- eTag: 77481C8EE (协商缓存,根据内容生成的唯一标志)
- if-modified-since:(协商缓存,修改时间请求头)
- if-none-match:(协商缓存,唯一标志请求头)
GET 和 POST 的区别
- get会被缓存,post不会缓存。
- get参数放在url里,post放在body里。
- get有长度限制,post没有限制。(谷歌8k)
- get是幂等的,post不是。(多次请求结果相同)
Cookie
cookie:服务端保存在浏览器的一小段数据。用于弥补http在状态管理上的不足。格式如下:
cookie: name1=value1; name2=value2; name3=value3;
设置cookie:通过响应头的set-cookie设置,或者用js的document.cookie设置。
有效期:通过expires和max-age来设置。
作用域:通过domain和path来设置。path=/表示所有路径都使用。
安全
- secure:只能通过https传输。
- httponly:只能通过http协议传输,不能通过js访问。(预防xss攻击)
- samesite:strict禁止跨域,lax在a标签导航可以跨域,none可以跨域。(预防csrf攻击)
缺点
- 容量:上限4K,只能储存少量信息。
- 性能:每次都会随着请求发送,浪费带宽。(可以通过domain和path优化)
- 安全:明文传输,会暴露敏感信息。
浏览器储存
- cookie:上限4K,会随http请求发送给服务端。
- localStorage:上限5M,持久储存。(应用场景:保存用户偏好,如主题色)
- sessionStorage:上限5M,会话级储存,页面关闭就消失。(应用场景:保存浏览记录)
- indexedDB:没有具体上限,大约几百M。(应用场景:储存大量数据)
cookie + session:一种经典的前端登录方案,cookie只是一个id,数据存在服务端。
token:另一种常见的登录方式,数据存在token里,加密后通过cookie或body发给服务端。
缓存
判断过程
- 客户端判断强缓存,如果可用返回200。
- 否则发送请求,服务端判断协商缓存,如果可用返回304,不可用返回新资源和200。
类型
- 强缓存
- expires:缓存到期时间(绝对时间)
- cache-control:缓存时长(相对时间)
- 协商缓存
- last-modified:最后修改时间
- etag:根据内容生成的唯一标志
优先级:cache-control > expires > etag > last-modified
cache-control字段
- no-store:不使用任何形式缓存
- no-cache:不使用强缓存,进入协商缓存阶段
- private:只允许浏览器缓存
- public:中间代理也可以缓存
- max-age:缓存时长
- s-maxage:代理缓存时长
last-modified和etag对比
- etag的精度更高。last-modified单位是秒,如果1秒内改变多次感知不到。编辑文件后,文件内容没有改变,last-modified也会变。
- last-modified的性能更好。last-modified只记录时间点,而etag需要根据内容生成哈希值。
缓存位置
- memory cache:较小的、使用频率高的文件
- disk cache:较大的,使用频率低的文件
跨域
同源策略:
- 同源是指两个url的协议、域名、端口相同。
- 不同源不能访问dom、cookie,也不能发送请求。
跨域常用方式:
- CORS(跨域资源共享):设置Access-Control-Allow-Origin:* 。
- JSONP:script标签不受跨域影响,但只能发送get请求。
- Nginx代理:后端发请求不受跨域影响。(跨域是浏览器进行拦截)
安全
跨站脚本攻击(xss)
- 定义:在网站注入恶意代码。
- 方式:
- 在输入框里注入(然后提交到服务器),页面展示的时候执行。(比如评论)
- 在url里注入(然后诱导用户点击),浏览器解析参数的时候执行。
- 预防:
- 对用户输入的内容进行转义。(让脚步不能执行)
- cookie设置httponly。(让cookie不能通过js访问,防止窃取cookie)
跨站请求伪造(csrf)
- 定义:冒充用户向服务器发送请求。
- 方式:诱导用户进入非法网站,向用户登录过的网站发送请求,会自动携带cookie。
- 预防:
- 设置samesite:lax/none。(跨域的时候不携带cookie)
- 使用token。(服务端给客户端生成一个token,请求的时候要验证token)
2.HTTP2
二进制分帧
问题:
- http1.1是文本格式,比较难处理。
方案:
- http2改为二进制格式,更方便。
- 一个请求会被分成多个帧。
多路复用
问题:(队头阻塞)
- 现在一个网页可能有上百个资源。
- 在http1.1中,1个tcp连接只能同时发1个请求(最多同时打开6个连接)。
方案:
- 在http2中,1个tcp连接同时发送多个请求(来自各个流的数据包会被混合在一起)。
头部压缩
问题:
- http header(cookie最多4k)比tpc和ip(20~60字节)大很多,是值得被优化的。
- 客户端从同一服务器请求大量资源的时候,很多请求头是一样的,一样的东西就可以被压缩。
方案:(HPACK算法)
- 用一张哈希表存常用的头部和对应的索引。
- 哈夫曼压缩。(统计字符出现频率,频率高的用短的索引表示)
服务端推送
- 允许服务端主动发送资源,如客户端请求html,不用等新的请求到来,主动推送css、js、图片,加快响应速度。
3.HTTP3
HTTP3前身是谷歌制定的QUIC(Quick UDP Internet Connection)协议,基于UDP,融合了TCP、TLS1.3、HTTP2的一些特性。
- 消除队头阻塞:多个stream之间没有依赖,丢包只影响1个stream。
- 改进的拥塞控制:默认用cubic算法。
为什么需要 HTTP3
因为TCP存在队头阻塞的问题,丢包后会等待重传。我们想要的其实是TCP2,顺便得到了HTTP3。
4.HTTPS
HTTPS是超文本传输协议的安全版本。HTTPS = HTTP + SSL/TLS。
为什么需要 HTTPS
- 明文传输
- 问题:会被窃听。
- 对称加密
- 作用:加密消息(成为乱码)。
- 问题:难以传递。
- 非对称加密
- 作用:传递对称密钥。
- 问题:无法验证身份(会被中间人替换)。
- 证书(受信任的CA的公钥会预安装在设备里)
- 作用:验证身份。
*对称加密:加密和解密的密钥相同。
*非对称加密:加密和解密的密钥不同。
*非对称加密很安全,但计算很慢,RSA2048解密需要几毫秒,难以规模化,所以只用来传递对称密钥。
*公钥和私钥互为锁和钥匙的关系。
握手过程
- 客户端送支持的TLS版本和加密算法列表。
- 服务端返回TLS版本、加密算法、公钥和证书。
- 客户端验证证书,生成对称密钥,用公钥加密后发送。
- 客户端发送一个测试消息。
- 服务端响应。
HTTP 和 HTTPS 的区别
- http使用80端口,https使用443端口。
- http明文传输,https加密传输更安全。
- https多了TLS握手。
SSL 和 TLS
- SSL(Secure Sockets Layer)是TLS的前身。
- TLS(Transport Layer Security)是传输层安全协议,在TCP协议之上,主流版本1.2,最新版本1.3。
5.DNS
DNS(Domain Name System)是一个把域名映射为IP地址的数据库。
DNS查询:浏览器缓存 -> 硬盘缓存 -> 路由器缓存 -> 本地DNS服务器 -> 根域名服务器 -> 顶级域名服务器(比如.com) -> 下级域名服务器
*互联网很小的时候,每个主机地址都存在一个HOSTS.TXT文件里。
二、传输层(Transport)
1.TCP
TCP(Transmission Control Protocol)协议是一个面向连接的、可靠的传输层协议。超过95%的网络应用使用TCP协议。
- 面向连接的:是一对一的协议,不能一对多,通过TCB(Transmission Protocol Block)来保存状态。
- 可靠的:丢包会重传,检验数据的顺序对不对、是否损坏。
TCP 报文头部
- 源端口(Source Port):源主机的端口号。
- 目标端口(Destination Port):目标主机的端口号。
- 序列号(Sequence):检测是否丢失。(如果序列号从1000开始,则第一个TCP段的序号为1000,如果该段有500字节数据,则下一个段序列号为1500)
- Flags:ACK、SYN、FIN用于三次握手和四次挥手。
- 窗口大小(Window Size):接收窗口的大小。
- 校验和(checksum):检测数据是否损坏。
三次握手
过程:
- 主机A向B发送一条
SYN消息,表示A的TCP层想和B的TCP层建立连接,同时发送一个基数,用于标识字节流中的字节(比如seq 1676510846)。 - B返回
SYN + ACK消息,ACK表示确认A的请求,并同意建立通信, SYN表示B的TCP层想和A的TCP层建立连接,同时发送一个数字,指示字节流的起始编号。(比如ack 1676510847,seq 715862251) - 最后A返回一个
ACK,表示接受通信请求,然后就建立起双向连接,开始发送数据。(比如 ack 715862252)
为什么是三次握手?
三次是保证客户端和服务器双方确认对方有发送和接受能力的最小次数。
四次挥手
- 主机A上的TCP层通过发送
FIN消息来关闭连接。 - 主机B发送
(Data +)ACK确认A不再有要发送的数据,并停止寻找来自A的新数据,A到B的数据流关闭。但B可能仍有新数据要发送。 - B发送完数据以后向A发送
FIN。 - A发送
ACK进行确认,等待2MSL后关闭连接。
为什么等待2MS?
等待2MSL(Maximum Segment Lifetime,报文最大生存时间)是为了确认B收到ack包。(如果没收到的话,2MSL内B会再发一个fin包)
为什么挥手比握手多一次?
因为ack和fin不能合并发送,因为服务端可能还有数据没发完。(但三次握手和四次挥手一样都是发了四条信息)
滑动窗口
滑动窗口用于流量控制。相比每收到一个ack,才发一个数据包,同时发送多个数据包效率更高。
- 允许同时发送多个无ack的数据包,数量为发送窗口大小。
- 收到ack的时候,更新窗口状态。
- (比如收到1、2、3、5的ack,回复的ack是2、3、4、4)
拥塞控制
拥塞控制有Tohoe、Reno、NewReno、BBR、CUBIC等算法。
基本原则是 AIMD,加性增加乘性减少,cwnd增长曲线呈锯齿形状。
TCP Tohoe 版本(1987年):
- 慢启动:从10个开始,每收到1个ack翻两倍,指数增长。
- 拥塞避免:达到慢启动阈值(ssthresh)后,线性增长。
- 拥塞:如果超时或收到重复ack,阈值设为cwnd的一半,重新开始慢启动。 *注意:刚开始没有ssthresh,发生第一次拥塞后才有
TCP Reno 版本(1990年):
- 超时情况与Tahoe相同。
- 快速重传:收到3个重复的ack时,不用等待超时,而是立即重传。
- 快速恢复:如果是收到重复ack,不用进入慢启动,而是cwnd减半,进入拥塞避免。
2016年,google提出了BBR算法,以带宽检测(而非以前的丢包检测)为导向进行拥塞控制。
拥塞窗口、接收窗口和发送窗口关系:
- 拥塞窗口:cwnd
- 接收窗口:rwnd
- 发送窗口:swnd = min(cwnd, rwnd)
保证数据可靠性
- 三次握手:确保对方有接受能力。
- ack:每发送会返回一个ack包,没收到会超时重传。
- checksum:验证数据包是否损坏。
- 拥塞控制和流量控制减少网络拥堵,侧面保证可靠性。
2.UDP
UDP(User Datagram Protocol)协议在应用之间提供更简单的数据报传递服务。
UDP 报文头部
UDP 应用
- DNS 使用UDP协议,超时会重新发送。
- QUIC 协议也基于UDP协议。
- 视频、音频等。
3.ICMP
ICMP(Internet Control Message Protocol)协议在主机和路由之间提供有关网络层的信息。
常用的 ICMP 消息类型
ICMP 应用
Ping 是基于Echo Request实现。
Traceroute 是基于TTL Expired实现。TTL(Time To Live)为0时,路由器会返回一条ICMP消息,依次设置TTL为1、2、3等,通过返回的ICMP消息可以知道经过了哪些路由器。
三、网络层(Network)
互联网是网络的网络(The internet is a network of networks)。
1.IP
IP(Internet Protocol)协议是互联网的基本协议。
IP 报文头部
源地址(Source IP Address):源主机的IP地址。
目标地址(Destination IP Address):目标主机的IP地址。
版本(Version):IPv4或者IPv6。
TTL(Time to Live):生命周期,每经过一跳减1。
校验和(Checksum):检测数据是否损坏。
路由中的一跳(Inside Each Hop)
路由器中有一个转发表(ForWarding Table),数据包到达时,路由器根据最长前缀匹配算法(LPM),检查哪个转发表条目最匹配数据包,并向该链接转发数据包,如171.33.5.245:
- 171.33.x.x ✔
- 23.x.x.x
- 171.32.x.x
端对端延迟(End-to-End Delay)
端对端延迟 = 打包延迟 + 传播延迟 + 排队延迟
Ping 用于测量计算机之间的端对端延迟。斯坦福到普林斯顿大约100ms,到清华大约200ms。
分割数据包能产生流水线效果(pipeline),减少端对端延迟,这也是为什么我们不在一个数据包中发送完整的数据。
IPv4 和 IPv6
- IPv4:点分十进制,如:
- IPv6:冒分十六进制,如:
IPv4地址不够用
通过NAT(Network Address Translator)解决,把一个公网地址映射成多个私网地址。
路由算法
- Bellman Ford
- Dijkstra
路由寻址协议
- 本地网络传输:OSPF
- 公网传输:BGP
四、链路层(Link)
以太网帧(Ethernet Frame Format):
MAC Protocals:
- Aloha
- CSMA/CD
信号传输方式:
- 光纤——光脉冲
- 铜线——电信号
- wifi——电磁波
参考
斯坦福大学CS144课程(双语字幕)
Web 协议详解与抓包实战
HTTP灵魂之问,巩固你的 HTTP 知识体系
✋🏼🔥 CS Visualized: CORS
http2 explained
HTTP/2 简介
High Performance Browser Networking
用信鸽来解释 HTTPS
HOW HTTPS WORKS(漫画)
HOW DNS WORKS(漫画)
How does the INTERNET work?(youtube)
How The Internet Works(youtube)
等等