TCP/IP协议族
-
数据链路层
- 实现网卡接口的网络驱动程序,隐藏物理网络的电气特性,为上层协议提供接口,实现【直连】的两个设备之间通信
- 主要协议
- ARP协议:提供IP地址到MAC地址的转换
- 工作原理:向自己所在网络广播一个ARP请求,被请求的目标机器回应包含自己MAC地址的ARP应答
- 工作过程:ARP模块封装好ARP请求/应答后交给以太网驱动程序加上以太网帧头部与尾部后,传输给LAN中的每个机器
*
- 硬件类型:1表示MAC地址
- 协议类型:0x800表示IP地址
- 硬件地址长度:MAC地址为6(字节)
- 协议地址长度:IPv4地址为4(字节)
- 操作:1表示ARP请求,2表示ARP应答,3表示RAPP请求,4表示RAPP应答
- ARP高速缓存:保存了一些常用的IP地址到MAC地址的映射
- ARP协议:提供IP地址到MAC地址的转换
-
网络层
-
实现数据的分包和选路,选择两台通信主机间的中间节点以确定通信路径,负责【没有直连】的两个网络之间的通信
-
主要协议
- IPv4协议:根据数据包目的IP决定如何投递和接收,头部大小:20+40字节
- 协议特点:为上层提供无状态无连接不可靠的服务
- 无状态:通信双方所有的数据传接相互独立,没有上下文关系,只要收到了完整数据包就重组后交给上层协议,而不处理乱序和重复
- 无连接:通信双方不维持对方的信息,上层协议每次发送数据必须制定对方的IP地址
- 不可靠:不保证数据包准确到达,IP协议只会通知上层协议发送失败,而不负责重传
- 协议特点:为上层提供无状态无连接不可靠的服务
- IPv6协议:IPv4的32位地址即将用尽,头部大小40字节
- 因为在数据链路层和传输层都会校验,故IPv6取消了首部校验和字段
- IPv6不允许在中间路由器进行分片与重组,以提高路由转发速度,故取消了分片/重新组装字段
- IP分片
- 通过三个头部字段:标识、标志、片偏移给予分片和重组信息
- 以太网帧MTU=1500字节,携带的IP数据部分最长1480(IP头部占20字节)
- 在IP分片中只有第一个分片需要承载上层协议的头部信息,比如TCP头部、ICMP头部
- ICMP协议:用于检测网络连接,头部大小:8字节
- 8位类型字段:区分报文为回应网络错误的差错报文或查询网络信息的查询报文
- 8位代码字段对报文类型进一步细分
- 16位校验和字段对整个报文做循环冗余校验
- 应用场景:当接收方UDP发现收到的报文中端口号不正确,将丢弃该报文,并由ICMP发送差错报文
- IPv4协议:根据数据包目的IP决定如何投递和接收,头部大小:20+40字节
-
-
传输层
-
实现两台主机上应用程序的端到端通信,只关注起点和终点,不关注中转过程
-
主要协议
-
TCP协议(传输控制协议):
-
特点
-
面向连接, 连接前需要三次握手
-
只提供一对一点对点的服务
-
保证数据可靠交付,不重复、不丢失、按序到达
-
确认应答和重传机制、流量控制、拥塞控制、保证传输安全性
-
首部大小为20~60字节
-
基于字节流,没有边界
-
分片方式:数据如果大于MSS将会在TCP层对数据进行分片传输,同样在TCP层进行合并
让传输层承担分片以及组装的任务,IP层只负责传输,当发生某个分片丢失后IP层可正常将其他分片交付给传输层,传输层再进行单个分片的重传
-
-
-
32位序列号:报文首字节的字节流编号,解决网络包乱序问题
-
本次报文序列号=上次发送的报文序列号+len
如果上一次报文是FIN或SYN报文,len=1
这里也可以从发送窗口理解,指针指向发送窗口第一个字节的序列号,当数据发送之后滑动窗口滑动,指针就指向的下一个序列号刚好就是上次序列号+len
-
如果是第一次握手或第一次挥手,序列号为初始化的client_isn或sever_isn
-
序列号会进行回绕,不严格递增:重传报文和丢失报文的序列号是一样的
-
-
32位确认号
- 本次确认号=上次收到的报文序列号+len
- 正常情况下,本次确认号即对方发送的下一个报文的序列号
- 确认号会进行回绕,不严格递增:重传ACK和丢失ACK的序列号是一样的
-
6位标志位(为1时有效)
- ACK标志:携带该标志的报文即为ACK报文
- RST标志:表示要求对方重新建立连接,携带该标志的报文即为复位报文段
- SYN标志:表示请求建立一个连接
- FIN标志:表示通知对方本端要关闭连接了
-
16位校验和:发送端填充,接收端以此执行CRC检验数据完整性
-
16位紧急指针:紧急指针相对于当前序号的偏移量,用以发送端向接收端发送紧急数据
- 紧急指针置为指向最后一个带外数据的下一个字节
-
选项
-
kind:说明选择的类型
-
length:说明该选项的总长度
-
info:选项的具体信息
-
常用7种TCP选项
-
kind=0:选项表结束,放在末尾用于填充,说明首部已经没有更多消息,数据在下一个32位数
-
kind=1:空操作,仅用来将TCP选项总长度填充为4字节的倍数
-
kind=2:通信双方以此选项协商最大报文段长度MSS,通常MSS为MTU-IP头部-TCP头部=MTU-40=1460
-
kind=3:通信双方以此选项,在TCP连接初始化时协商接收窗口的扩大因子(因为TCP模块所允许的接收窗口远远不止16位窗口大小所表示的65535个字节)
如果扩大因子是M,那么实际上的接收窗口大小为N左移M位,但该选项只能出现在同步报文,一旦确定了之后在当前连接下就不再改变
-
kind=4:选择性确认SACK选项
-
kind=5:选择性确认SACK实际工作的选项,该选项的参数告知发送方有哪些数据块已经收到了
-
kind=8:时间戳选项,提供了精确的计算RTT的方法
-
TFO(TCP fast open)选项
-
首次通信时客户端的SYN报文携带该选项并将cookie置空,服务端生成cookie由客户端缓存
-
之后通信时,客户端首次握手即发送SYN+cookie+data,服务端验证cookie有效后便可绕过TCP三次握手直接传输数据,若无效则丢弃数据进行SYN+ACK
-
-
-
-
-
-
UDP协议
-
特点
- 面向无连接,即刻传输数据
- 支持一对一,一对多,多对多通信
- 尽可能交付,不保证可靠性
- 即使网络拥堵也不会降低发送速率
- 首部大小固定为8字节
- 基于数据包传输数据,可能发生乱序和丢包
- 分片方式:数据大于MTU时在IP层进行分片,同样在IP层进行合并
-
-
-
TLS协议:为HTTP通信提供安全保证,解决窃听风险、篡改风险、冒充风险
-
RSA算法:
- 服务端保管一个固定的私钥,将公钥发给客户端
- 客户端生成随机数,并用服务端公钥加密后发给服务端
- 服务端用私钥解密后,双方计算出会话密钥
- 一旦服务器的私钥被获取了就寄了,不具有前向安全性
-
ECDHE算法:
- 事先决定使用的椭圆曲线以及基点G
- C和S各自有一个私钥dc和ds,分别与G相乘得到公钥Gc和Gs
- 会话秘钥=对方的公钥*自己的私钥=dc * Gs=dc * ds * G=ds * Gc
- 私钥是随机生成的动态变化的,具有前向安全性
-
摘要算法:对HTTP通信内容计算出一个哈希值,作为内容的标识
-
数字签名:用服务端私钥对哈希值加密,分发服务端公钥给客户端,顺利解密说明哈希值有效
-
数字证书:CA机构私钥对服务端注册的公钥签名,分发CA公钥给客户端,顺利解密说明服务端公钥有效
-
优化方向:选用ECDHE密钥交换算法;选择计算最快的x25519椭圆曲线;TLS1.3新特性:出现Pre-shared-key,服务端将会话秘钥加密为ticket由客户端保存,客户端将ticket和HTTP请求一起发给服务端,服务端解密后若有效期无误即可对话,实现0RTT
-
-
QUIC协议:
- 以连接ID标记一个连接,即使某方IP变化,只要保有上下文信息(连接ID、TLS密钥等)即可丝滑复用连接
- QUIC握手+TLS握手时延:1RTT,不分层,在QUIC帧中直接携带TLS的信息记录,甚至第二次握手时可让握手信息携带应用数据包实现0RTT
- 使用两个特殊单向流Encoder Stream和Decoder Stream同步双方动态表,前者用于告知编码方需要加入哪些字段到动态表,后者用以响应告知解码方,编码方收到解码方的更新确认通知后才开始编码HTTP头部
- 每个Stream有独立的滑动窗口,某个Stream报文丢失其他Stream也可照常读取,解决Stream-队头阻塞
- 序列号严格递增
- 精准分辨重传报文ack和原报文ack,从而精准计算RTO(在TCP连接中,由于重传报文ack和原报文ack的序列号相同,无法分辨取哪个作为计算基准)
- 通过特殊的数据帧ACK fream以及ACK block来支持乱序确认,在ACK fream中有多个block记录已经接收数据的序号范围,滑动窗口只要有新数据确认就会继续滑动,不需按序接收,等接收之后通过Stream ID和Offset字段信息,组装乱序的数据段
- 在应用层实现拥塞控制,不需内核支持,可随浏览器灵活更新
- 运行原理
- packet long header:首次连接使用,协商建立连接ID
- packet short header:日常传输使用,只需要目标连接ID,而不需要源ID
- packer number:严格递增的序列号
- Stream:常见的Fream类型
-
Stream ID:区分多个并发传输的HTTP消息
-
Offset:保证数据顺序和可靠性,实际上承担大部分TCP序列号任务
-
-
-
-
应用层
-
实现应用程序的逻辑处理,在用户空间实现
-
主要协议
-
ping应用程序:调试网络环境的必备工具
-
telnet协议:远程登录协议,在本地完成远程任务
-
OSPF协议:动态更新路由,用于路由器间通信
-
DNS协议:提供机器域名到IP地址的转换
-
工作原理:DNS是一个分布式的域名服务系统,每个服务器上存放动态更新的机器名与IP地址的映射,客户端程序向DNS服务器请求以查询目标主机IP地址
-
-
16位标识:用以标记一对DNS查询与应答
-
16位标志:用以表示该DNS报文的类型(如是查询报文还是应答报文,是什么类型的查询)
-
查询问题:查询名封装要查询的主机域名,查询类为1表示获取IP地址
-
应答、授权、额外信息字段都是用资源记录(RR)格式
-
-
-
HTTP协议:在计算机世界的两点之间传输文字图片音频等超文本数据的约定和规范,即超文本传输协议
-
HTTP请求报文
-
HTTP响应报文
-
Host:指定服务器域名
-
Content-Length:本次服务器回应的数据长度,定义了HTTP body的边界,防止沾包
-
Content-Type:本次服务器选择的数据格式
- 对应的,客户端用 Accept:告诉服务器它可以接受什么格式的数据
-
Content-Encoding:本次服务器选择的数据压缩格式
- 对应的,客户端用Accept-Encoding
- Accept:客户端可在该字段里的Q质量因子告知有损压缩所期望的质量
-
Connection:客户端是否要求服务器使用HTTP长连接
-
方法
- GET:从服务器获取指定的资源
- 客户端发送GET请求给服务器,服务器以对应的网页作为响应
- GET的参数写在URL中,只能是ASCII格式,且浏览器对这个长度有所限制
- GET只产生一个TCP数据包,浏览器把请求头和请求数据一并发出
- 只读操作,故安全(不会篡改服务器内容),幂等(相同操作相同结果),可缓存(下一次传输的数据相同就返回缓存中的内容)
- POST:根据请求负荷实体(entity body)对指定资源做出处理
- POST的数据一般放在body里,对格式没有要求,且浏览器对这个长度没有限制
- 会处理指定资源,故不安全,不幂等,不能缓存
- POST会产生两个TCP数据包,浏览器先发请求头,然后再发请求数据
- 应用场景:用户提交表单时,如搜索关键词时使用POST报文,Web网页的具体内容依赖于用户在表单字段输入的内容
- PUT:上传某个资源
- DELETE:删除某个资源
- HEAD:与GET类似,只要求服务器返回头部信息
- GET:从服务器获取指定的资源
-
状态码
- 1开头,待处理
- 2开头,成功,比如200,204,206
- 3开头,重定向(资源位置变化),比如301,302,304
- 4开头,客户端错误(请求报文有误,服务器无法处理)比如400,403,404
- 5开头,服务器错误,比如500,501,502,503
-
协议更新
- HTTP/1.1
- 协议特性
- 简单:报文格式头部信息都是简单文本形式
- 灵活:请求方法允许开发人员自定义;下层协议信道可选择
- 无状态:服务器不记忆HTTP状态信息,减轻服务器负担
- 可使用cookie缓存记忆状态。用以完成有关联性的操作
- 明文传输:可使用Wireshark抓包直接查看传输过程的信息,方便调试
- 不安全
- 通信明文传输,内容可能被窃听
- 不验证通信方身份,有可能遭遇伪装
- 无法证明报文完整性,有可能已遭篡改
- 默认使用长连接
- 管道网络传输(默认关闭):可不考虑响应情况接连发出多个请求
- HTTP头部冗长重复,使用ASCLL编码
- 不支持服务器主动推送消息
- TCP三次握手时延:2RTT
- 默认端口号80
- 可选用HTTP keepalive:在请求头中加入Connecttion:keep-alive,通知对端在该请求响应完成之后不要关闭
- 队头阻塞:同一连接只能在完成一个HTTP事务(请求-响应)后才能处理下一个事务
- 请求-队头阻塞:在收到上一个请求的响应前,待发送的请求都要等
- 响应-队头阻塞:在处理好上一个响应前,待处理的回应都要等
- HTTPS:超文本安全传输协议
- 协议特性
- 在TCP和HTTP之间加入SSL/TLS安全协议
- 默认端口号443
- 信息加密:通过非对称加密交换会话秘钥;通过对称加密加密明文数据,混合加密技术保证数据不被窃听
- 校验机制:摘要算法给每个内容标识一个哈希值,服务端用自己的私钥对哈希值加密,若分发给客户端的公钥能顺利解密说明消息未被篡改(私钥加密公钥解密)
- 身份证书:向CA申请数字证书,CA机构用自己的私钥给服务器注册的公钥签名,客户端取得服务端数字证书后用CA的公钥确认服务端数字证书的真实性,保证服务器身份可信
- 绝对安全,即使有假基站作为中转要盗取会话信息,也会因为网站证书问题被识破
- 可进行HTTPS双向认证
- 优化方向
- 硬件优化:使用支持AES-NI的CPU,提升算力且优化AES算法
- 软件升级:存在风险,不是主流方案
- TLS协议优化
- 证书优化:使用密钥长度较短的ECDSA证书;使用OCSP在线证书协议状态,在线向CA发送查询请求,并进行OCSP stapling,服务器周期性地查询证书状态并缓存
- 会话复用,使用TLS1.3,利用客户端缓存ticket,实现会话复用
- HTTP/2.0
- 帧类型:定义剩余的帧报头和主体将如何被解释,分为数据帧和控制帧
- 标志位:标识对于确定的帧类型赋予特定的语义
- R:保留字段
- 流标识符:标识连接内的某个流;客户端创建的流为奇数,服务端为偶数;新建流的标识符要大于已有流和预留流的标识符;当终端的流标识符耗尽,对于客户端来说需要关闭连接腾出空间创建新流;对于服务端来说需要发送一个GOAWAY帧通知客户端打开一个新连接
- 协议特性
- 头部压缩:为头部中高频出现的字符串和字段建立静态表,通过哈弗曼编码由index索引到不同的header value;在61种静态字符串范围外的头部字符串建立动态表,idx从62开始,在同一个连接上重复传输相同的HTTP头部时生效
- 二进制分帧:帧有很多个类型,有的帧用来控制打开一个流,有的帧用来关闭一个流,多个流并发实现HTTP/1中通过多个TCP连接才能实现的并发;同时二进制编码更加高效
- 通过二进制分帧实现同域名下的所有通信都在单个TCP连接中完成,传统的HTTP/1.1需要开多个TCP连接才能实现并发
- Stream设计:
- 是一个存在于连接中的虚拟通道,相同流标识的帧按顺序组装为流
- 单独的HTTP/2连接能保持多个同时打开的流,各个端点从多个流中交换帧
- 在同一个Stream里,通过每个帧头部的Stream ID严格有序组装成HTTP消息
- 在同一条TCP连接里的Stream ID顺序递增,但支持不同Stream帧的乱序接收,实现并发
- 同时支持在帧头的标志位设置优先级,给每个Stream设置不同优先级
- Stream里包含1个或多个Message(对应HTTP/1中的请求或响应)
- Message里包含1个或多个Frame(Frame是HTTP/2的最小单位)
- Frame里包含1个或多个TCP报文
- 支持服务端主动推送消息:通过
PUSH_PROMISE帧传输HTTP头部,以及Promise Steam ID字段告知客户端接下去在哪个偶数号Steam发送包体 - 美中不足:基于TCP实现
- Stream-队头阻塞:由于TCP要求数据接收完整有序,如果某个Stream里的报文丢了,其他Stream报文即使接受了也不能读取,导致请求堵塞
- 动态表-队头阻塞:双方在首次请求建立动态表,若首次请求丢包导致后续请求因动态表未建立而无法解码,导致请求堵塞
- TCP三次握手+TLS四次握手时延:3RTT,分层,要先TCP握手再进行TLS握手
- 不利于移动设备网络切换:由四元组标记一个连接,当IP与端口变动需要重新握手
- HTTP/3
- 协议特性
- 传输层协议更换为UDP协议,无需握手无需挥手无需连接
- 在应用层使用具有连接管理、拥塞窗口、流量控制的QUIC协议,同时自身不需再定义Stream,直接使用QUIC里的Stream
-
优化方向
- 减少发送HTTP请求:HTTP缓存
- 强制缓存:浏览器通过HTTP响应头部判断缓存未过期则直接使用缓存
- Cache-Control:相对时间,服务端每次接受请求都在该字段更新过期时间
- Expires:绝对时间
- 协商缓存:服务端通过HTTP响应头部和请求头部协商决定是否使用缓存
- 响应头部Etag—请求头部If-None-Match:在该请求头部带上缓存资源的唯一标识Etag,服务端对比Etag判断缓存内容是否变化
- 响应头部Last-Modified—请求头部If-Modified-Since:在请求头部带上缓存资源的last-Modified,服务端对比判断是否变化
- 减少发送HTTP请求:HTTP缓存
-
减少HTTP请求次数:通过代理服务器承担资源重定向请求的任务;通过
CSS Image sprites技术合并图片或服务端webpack合并js、css资源合并请求从而减少连接数量,节省TCP握手和慢启动时间;按需获取的方式延迟响应请求 -
减少HTTP响应的数据大小:压缩数据无损压缩技术如
gzip和brotli;有损压缩技术如针对图片的webp格式
-
-
-
Websocket协议:实现客户端和服务端的全双工通信,浏览器也可主动发送数据
- 4位opcode:用以标志数据帧类型
- 7位Payload和拓展Payload长度:用以携带真正想传输的数据的长度
-
工作原理:在服务端和客户端已经建立TCP连接的前提下,Websocket会利用HTTP协议加上一些特殊的header头进行握手升级操作
connection:Upgrade Upgrade:WebSocket Websocket-Key:XXX- 随机生成的WebSocket-Key码发送给服务端,服务端用公开算法将其转换为字符串,然后发送给客户端,且状态码为101意为协议切换
- 客户端也将WebSocket-Key转化为字符串,若与服务端传回的字符串一致则连接成功
-
DHCP协议(动态主机配置协议)通过DHCP动态获取IP地址,省去配置IP信息的过程
-
-
cookie:第一次登陆服务器之后,服务器为标识该用户浏览的内容,给浏览器返回的数据叫做cookie,存储在本地浏览器,接下去请求的时候浏览器直接发cookie给服务器,服务器就能识别是哪个用户,存储数据有限
session:存储在服务器的数据,对存储数据大小没有限制,会占用服务器资源但是存在服务器上更加安全