网络体系结构概述
分层的基本原则
- 每层都实现一种相对独立的功能,降低大系统的复杂度。
- 各层之间界面自然清晰,易于理解,相互交流尽可能少。
- 各层功能的精确定义独立于具体的实现方法,可以采用最合适的技术来实现。
- 保持下层对上层的独立性,上层单向使用下层提供的服务。
- 整个分层结构应能促进标准化工作。
5层协议
应用层
为特定应用程序提供数据传输,例如HTTP,DNS,数据单位为报文
传输层
为进程提供通用数据传输服务。由于应用层的传输协议很多,定义通用的传输层协议就可以不断增加应用层协议。
传输层包括两种:
- 传输控制协议TCP,提供面向连接,可靠的数据传输服务,数据单位为报文段
- 用户数据报协议UDP,提供无连接,尽最大努力交付的数据传输服务,数据单位为用户数据报。
TCP主要提供完整性服务,UDP主要提供及时性服务
网络层
为主机提供数 据传输服务。而传输层协议就是为主机中的进程提供数据传输服务。网络层把数据层传输下来的报文段或者用户数据包封装成分组
数据链路层
网络层针对的还是主机之间的数据传输服务,而主机之间可以有很多链路,链路层协议就是为了同一链路的主机提供数据传输服务。数据链路层把网络层传下来的分组封装成帧。
物理层
物理层考虑的是怎样传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异
OSI七层协议
增加了会话层和表示层。五层协议没有表示层和会话层,而是将这些功能留给应用程序开发者处理。
表示层
表示层主要处理在两个通信系统中交换信息的表示方式。
不同机器采用的编码和表示方法不同,使用的数据结构也不同。为了使不同表示方法的数据和信息之间能互相交换,表示层采用抽象的标准方法定义数据结构,并采用标准的编码形式。
表示层还提供的功能有:数据压缩、加密和解密(数据表示变换功能)。数据压缩,加密以及数据描述,这使得应用程序不必关心在各台主机中的数据格式不同的问题
会话层
管理会话
会话层允许两个不同主机上的各个进程之间进行会话。
会话层主要为表示层实体或者用户进程建立连接并在连接的上有序地传输数据,这就是会话,也称为建立同步
会话层负责管理主机间地会话进程,包括建立、管理及终止进程间的会话。它可以使用检验点使通信会话在通信失效时从检验点继续恢复通信,实现数据同步。
TCP/IP
主要差别是网络接口层,TCP/IP协议中的网络接口层约等于五层协议中的数据链路层和物理层
对应OSI模型中的物理层和数据链路层,它表示与物理网络的接口,但是实际上TCP/IP本身并没有真正描述这一部分,只是指出主机必须使用某种协议与网络连接,以便在其上传递IP分组
具体的物理网络既可以是各种类型的局域网,如以太网、令牌环网、令牌总线网。也可以是公共数据网,如电话线、SDH、X.25、帧中继、ATM等。
主要作用:从主机或者结点接收IP分组,并把他们发送到指定的物理网络上
数据在各层之间的传递过程
在向下的过程中,需要添加下层协议所需要的首部或者尾部,而向上的过程中不断拆开首部和尾部
路由器只有下面三层,因为路由器位于网络核心中,不需要进程或者应用程序提供服务,因此也就不需要传输层和应用层。
物理层
概述
传输单位:比特
任务:透明的传输比特流
功能:在物理媒体上为数据端设备透明地传输原始比特流
物理层主要定义数据终端设备和数据通信设备地物理与逻辑连接方法
物理层协议也称为物理层规程
主要研究如下
- 通信链路与通信结点地连接需要一些电路接口,物理层规定了这些接口的一些参数
- 物理层规定了通信链路上传输的信号的意义和电器特征,比如规定信号A表示数字0
通信方式
根据信息在传输线上的传送方向,分为以下三种通信方式
- 单工通信:单向传输
- 半双工通信:双向交替传输
- 全双工通信:双向同时传输
数据链路层
基本特征
封装成帧
将网络层传下来的分组添加首部和尾部,用于标记帧的开始和结束
透明传输
透明表示一个实际存在的事物看起来好像不存在一样
帧使用首部和尾部进行定界,如果帧的数据部分含有和首部尾部相同的内容,那么帧的开始和结束为止就会被错误的判断。需要在数据部分出现首部尾部相同内容前面插入转义字符。如果数据部分出现转义字符,那么需要在转义字符前面再加一个转义字符。在接收段进行处理后可以还原出原始数据。这个过程透明传输的内容是转义字符,用户察觉不到转义字符的存在
差错检测
目前数据链路层广泛使用了循环冗余校验(CRC)来检查比特差错
信道分类
广播信道
一对多通信,一个节点发送的数据能够被广播信道上的所有节点收到
所有的节点都在同一广播信道上发送数据,因此需要有专门的控制方法进行协调,避免发生冲突(冲突也叫碰撞)
冲突:
冲突是指在同一个网段上,同一个时刻只能有一个信号在发送,否则两个信号相互干扰,即发生冲突。冲突会阻止正常帧的发送
主要有两种控制方法进行协调,一个是使用信道复用技术,一是使用CSMA/CD协议
点对点信道
一对一通信,使用ppp协议进行控制
信道复用技术
频分复用技术
频分复用的所有主机在相同的时间占用不同的频率带宽资源。
时分复用技术
时分复用的所有主机在不同的时间占用相同的频率带宽资源。
使用频分复用和时分复用进行通信,在通信的过程中主机会一直占用一部分信道资源。但是由于计算机数据的突发性质,通信过程没必要一直占用信道资源而不让出给其它用户使用,因此这两种方式对信道的利用率都不高。
统计时分复用技术
是对时分复用的一种改进,不固定每个用户在时分复用帧中的位置,只要有数据就集中起来组成统计时分复用帧然后发送。
波光复用
光的频分复用。由于光的频率很高,因此习惯上用波长而不是频率来表示所使用的光载波。
ppp协议
互联网用户通常需要连接到某个 ISP 之后才能接入到互联网,PPP 协议是用户计算机和 ISP 进行通信时所使用的数据链路层协议。
PPP的帧格式
- F字段为帧的定界符
- A和C字段暂时没有意义
- FCS是使用CRC的校验序列
- 信息部分的长度不超过1500
Mac地址
Mac地址是链路层地址,长度为6字节,用于唯一标识网络适配器(网卡)
一台主机拥有多少个网络适配器就有多少个Mac地址。例如,笔记本电脑普遍存在无限网络适配器和有限网络适配器,因此就有两个Mac地址
局域网
局域网是一种典型的广播信道,主要特征是网络为一个单位所有,且地理范围和站点数目有限
主要有以太网,令牌环网,FDDI,ATM等局域网技术,目前以太网占领着有线局域网的时长
可以按照网络拓扑结构对局域网进行分类
以太网帧格式
- 类型:标记上层使用的协议
- 数据:长度在46-1500之间,如果太小则需要填充
- FCS:帧校验序列,使用的是CRC校验方法
虚拟局域网
虚拟局域网可以建立与物理位置无关的逻辑组,只有在同一个虚拟局域网的成员才会收到链路层广播消息
例如下图中 (A1, A2, A3, A4) 属于一个虚拟局域网,A1 发送的广播会被 A2、A3、A4 收到,而其它站点收不到。
网络层
因为网络层是整个互联网的核心,因此应该让网络层尽可能简单。网络层向上只提供简单灵活的,无连接的,尽最大努力交付的数据报服务。
使用IP协议,可以把异构的物理网络连接起来,使得在网络层看起来好像是一个同一个网络
与IP协议配套使用的还有三种协议
- 地址解析协议ARP(Address Resolution Protocol)
- 网际报文控制协议ICMP(Internet Control Message Protocol)
- 网际组管理协议IGMP(Internet Group Management Protocol)
IP数据报格式
- 版本:有4(IPV4)和6(IPV6)两个值
- 首部长度:占4位,因此最大值为15。值为1表示的是1个32位的长度,也就是4个字节。因为固定部分长度为20个字节。因此该值最小为5。如果可选子段的长度不是4字节的整数倍,就用尾部的填充部分来填充
- 区分服务:用来获取更好的服务,一般情况下不使用
- 总长度:包括首部长度和数据部分长度
- 生存时间:TTL,它的存在是为了防止无法交付的数据报在互联网不断兜圈子。以路由器跳数为单位,当TTL为0就丢弃数据包
- 协议:指出携带的数据应该上交给哪个协议进行处理,例如ICMP,TCP,UDP等
- 首部校验和:因为数据包经过每一个路由器,都要重新计算校验和,因此校验和不包含数据部分可以减少计算的工作量
- 标识:在数据报文长度过长从而发生分片的情况下,相同数据包的不同分片具有相同的标识
- 片偏移:和标识符一起,用于发生分片时。片偏移的单位为8字节
IP地址编码方式
分类
由两部分组成,网络号和主机号组成,其中不同分类具有不同的网络号查高度,并且是固定的
IP地址::={<网络号>,<主机号>}
子网划分
通过在主机号字段中拿一部分作为子网号,把二级IP地址划分为三级IP 地址
IP 地址 ::= {< 网络号 >, < 子网号 >, < 主机号 >}
要使用子网,必须配置子网掩码。一个B类地址的子网占两个比特,那么子网掩码为 11111111 11111111 11000000 00000000,也就是 255.255.192.0。
注意,外部网络看不到子网的存在。
无分类
无分类编址CIDR消除了传统A类,B类,C类地址以及划分子网的概念,使用网络前缀和主机号来对IP地址进行编码,网络前缀根据需要变化
IP 地址 ::= {< 网络前缀号 >, < 主机号 >}
CIDR 的记法上采用在 IP 地址后面加上网络前缀长度的方法,例如 128.14.35.7/20 表示前 20 位为网络前缀。
CIDR的地址掩码可以继续成为子网掩码,子网掩码首1长度为网络前缀的长度
一个CIDR地址块中有很多地址,一个CIDR表示的网络就可以表示原来的多个网络,并且在路由表中只需要一个路由就可以代替多个路由,减少了路由表项的数量。把这种通过使用网络前缀来减少路由表项的方式成为路由聚合,也成为了构成超网
在路由表中的项目由网络前缀和下一条地址组成,在查找时可能会得到不止一个匹配结果,应当采用最长前缀匹配来确定匹配
地址解析协议ARP
网络层实现主机之间的通信,而链路层实现具体每段链路之间的通信。因此在通信过程中,IP数据报的源地址和目的地址始终不变,而Mac地址随着链路的改变而改变
ARP实现路由IP地址得到Mac地址
每个主机都有一个ARP高速缓存,里面有本局域网上各主机和路由器的IP地址到Mac地址的映射表
如果主机A知道主机B的IP地址,但是ARP高速缓存中没有该IP地址到Mac地址的映射,此时主机A通过广播的方式ARP请求分组,主机B收到请求后发送ARP响应分组给主机A告诉其Mac地址,随后主机A向其告诉缓存中写入主机B的IP地址到Mac地址的映射
网际报文控制协议(ICMP)
ICMP是为了更有效地转发IP数据包和提高交付成功的机会。它封装在IP数据报中,但是不属于高层协议
ICMP报文分为差错报告报文和询问报文
Ping
- Ping是ICMP的一个重要应用,主要用来测试两台主机的连通性
- Ping的原理是通过向目的主机发送ICMP Echo请求报文,目的主机收到后发送Echo回答报文。Ping会根据时间和成功响应的次数估算出数据包往返时间以及丢包率
Traceroute
Traceroute是ICMP的另一个应用,用来跟踪一个分组从源点到终点的路径
Traceroute发送IP数据报封装的是无法交付的UDP数据包,并且目的主机发送终点不可达差错报告报文
源主机向目的主机发送一连串的IP数据报。第一个数据报P1的生存时间TTL设置为1,当P1到达路径上的第一个路由器R1时,R1收到它并把TTL减1,此时TTL等于0,R1就把P1丢弃,并向源主机发送一个ICMP时间超时差错报告报文
源主机接着发送第二个数据报 P2,并把 TTL 设置为 2。P2 先到达 R1,R1 收下后把 TTL 减 1 再转发给 R2,R2 收下后也把 TTL 减 1,由于此时 TTL 等于 0,R2 就丢弃 P2,并向源主机发送一个 ICMP 时间超过差错报文。
不断执行这样的步骤,直到最后一个数据报刚刚到达目的主机,主机不转发数据报,也不把 TTL 值减 1。但是因为数据报封装的是无法交付的 UDP,因此目的主机要向源主机发送 ICMP 终点不可达差错报告报文。
之后源主机知道了到达目的主机所经过的路由器 IP 地址以及到达每个路由器的往返时间。
路由器结构
路由器从功能上可以划分为:路由选择和分组转发(路由表和转发表)
分组转发结构由三个部分组成:交互结构,一组输入端口,一组输出端口
路由器分组转发流程
- 从数据包的首部提出目的主机的IP地址D,得到目的网路地址N(网络地址)
- 若N就是与此路由器直接相连的某个网络地址,则直接进行交付
- 若路由器中有目的地址为D的特定主机路由,则把数据包传送给表中所指明的下一条路由
- 若路由表中有到达网络N的路由,则把数据报传送给路由表所指明的下一条路由器
- 若路由表中有一个默认路由,则把数据包传送给路由表中所指定的默认路由器
- 报告转发分组3出错
路由选择协议
路由选择协议都是自适应的,能随着网络通信量和拓扑结构的变化而自适应进行调整
互联网可以划分为许多较小的自治系统AS,一个AS可以使用一种和别的AS不同的路由选择协议
可以把路由选择协议分为两类
- 自治系统内部的路由选择。RIP 和 OSPF
- 自治系统间的路由选择hh。BGP
内部网关协议RIP
RIP 是一种基于距离向量的路由选择协议 。距离是指跳数,直接相连的路由器跳数为。最多跳数为15,超过15表示不可达
RIP按照固定的时间间隔和相邻路由器交换自己的路由表,经过若干次交换后,所有路由器最终会知道达到本自治系统中任何一个网络的最短距离和下一跳路由器地址
距离向量算法
对地址为X的相邻路由器发来的RIP报文,先修改报文中的所有项目,把下一跳中的地址改为X,并把所有距离字段加1
对修改后的RIP报文中的每一个项目,进行如下操作:
- 若原来的路由表中没有目的网络N,则把该项目添加进路由表中
- 否则;若下一跳路由器地址是X,则把收到的项目项目替换原来路由表中的项目;否则:若收到的项目中的距离小于路由表中的距离,则进行更新(例如原始路由表项为 Net2, 5, P,新表项为 Net2, 4, X,则更新);否则什么也不做。
- 若 3 分钟还没有收到相邻路由器的更新路由表,则把该相邻路由器标为不可达,即把距离置为 16。
RIP 协议实现简单,开销小。但是 RIP 能使用的最大距离为 15,限制了网络的规模。并且当网络出现故障时,要经过比较长的时间才能将此消息传送到所有路由器
OSPF
开放最短路径优先OSPF,为了克服RIP缺点而开发出来的,最短路径优先使用了Dijkstra提出的最短路径算法SPF
OSPF解释:
向本自治系统中的所有路由器发送消息,这种方法是洪泛法(洪泛攻击)
发送的信息就是与相邻路由器的链路状态,链路状态包括与哪些路由器以及链路的度量,度量费用,距离,时延,带宽
只有当链路状态发生变化时,路由器才会发送信息
传输层
网络层只把分组发送到目的主机,但是真正通信的并不是主机而是主机中的进程。传输层提供了进程间的逻辑通信,传输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个传输层实体之间有一条端到端的逻辑通信信道。
UDP和TCP的特点
用户数据报协议 UDP(User Datagram Protocol)是无连接的,尽最大可能交付,没有拥塞控制,面向报文(对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部),支持一对一、一对多、多对一和多对多的交互通信
传输控制协议 TCP(Transmission Control Protocol)是面向连接的,提供可靠交付,有流量控制,拥塞控制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),每一条 TCP 连接只能是点对点的(一对一)
UDP首部
首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。12 字节的伪首部是为了计算检验和临时添加的。
TCP首部
- 序号 :用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100字节,那么下一个报文段的序号应为 401。
- 确认号 :期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。
- 数据偏移 :指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。
- 确认 ACK :当 ACK=1 时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1。
- 同步 SYN :在连接建立时用来同步序号。当 SYN=1,ACK=0 时表示这是一个连接请求报文段。若对方同意建立连接,则响应报文中SYN=1,ACK=1。
- 终止 FIN :用来释放一个连接,当 FIN=1 时,表示此报文段的发送方的数据已发送完毕,并要求释放连接。
- 窗口 :窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。(接受方手段)
TCP的三次握手
- 假设 A 为客户端,B 为服务器端。
- 首先 B 处于 LISTEN(监听)状态,等待客户的连接请求。
- B收到连接请求报文,如果同意建立连接,则向 A 发送连接确认报文,SYN=1,ACK=1,确认号为 x+1,同时也选择一个初始的序号 y。
- A 收到 B 的连接确认报文后,还要向 B 发出确认,确认号为 y+1,序号为 x+1
- B 收到 A 的确认后,连接建立。
三次握手的原因
- 第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。
- 客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到服务器端发回的连接确认。客户端等待一个超时重传时间之后,就会重新请求连接。但是这个滞留的连接请求最后还是会到达服务器,如果不进行三次握手,那么服务器就会打开两个连接。如果有第三次握手,客户端会忽略服务器之后发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。
TCP的四次挥手
- A 发送连接释放报文,FIN=1。
- B 收到之后发出确认,此时 TCP 属于半关闭状态,B 能向 A 发送数据但是 A 不能向 B 发送数据。
- 当 B 不再需要连接时,发送连接释放报文,FIN=1。
- A 收到后发出确认,进入 TIME-WAIT 状态,等待 2 MSL(最大报文存活时间)后释放连接。
- B 收到 A 的确认后释放连接。
四次挥手的原因
客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。
TIME_WAIT
客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:
- 确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
- 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。
TCP的可靠传输
TCP 使用超时重传来实现可靠传输:如果一个已经发送的报文段在超时时间内没有收到确认,那么就重传这个报文段。
TCP滑动窗口
窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各自有一个窗口,接受方通过TCP报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其他信息设置自己的窗口大小。
发送窗口内的字节都允许被发送,接受窗口内的字节都允许被接受。如果发送窗口左部的字节已经发送并且收到确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接受窗口的滑动类似,接受窗口左部分字节都已经发送确认并交付主机,就向右滑动接受窗口
接受窗口只会对最后一个按序达到的字节进行确认,例如接受窗口已经收到字节{31, 34, 35},其中 {31} 按序到达,而 {34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收
TCP流量控制
流量控制是为了控制发送方发送速率,保证接收方来得及接收。
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
TCP拥塞控制
如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。
发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,注意拥塞窗口与发送方窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。
接收方有足够大的接收缓存,因此不会发生流量控制;
虽然 TCP 的窗口基于字节,但是这里设窗口的大小单位为报文段。
慢开始与拥塞避免
- 发送的最初执行慢开始,令 cwnd = 1,发送方只能发送 1 个报文段;当收到确认后,将 cwnd
加倍,因此之后发送方能够发送的报文段数量为:2、4、8 … - 注意到慢开始每个轮次都将 cwnd 加倍,这样会让 cwnd增长速度非常快,从而使得发送方发送的速度增长速度过快,网络拥塞的可能性也就更高。设置一个慢开始门限 ssthresh,当 cwnd >=ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。
- 如果出现了超时,则令 ssthresh = cwnd / 2,然后重新执行慢开始。
快重传与快恢复
在接收方,要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。
在发送方,如果收到三个重复确认,那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。
在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,令 ssthresh = cwnd / 2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。
慢开始和快恢复的快慢指的是 cwnd 的设定值,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。
应用层
域名系统
DNS 是一个分布式数据库,提供了主机名和 IP 地址之间相互转换的服务。这里的分布式数据库是指,每个站点只保留它自己的那部分数据。
域名具有层次结构,从上到下依次为:根域名、顶级域名、二级域名。
DNS 可以使用 UDP 或者 TCP 进行传输,使用的端口号都为 53。大多数情况下 DNS 使用 UDP 进行传输,这就要求域名解析器和域名服务器都必须自己处理超时和重传从而保证可靠性。
在两种情况下会使用 TCP 进行传输
- 如果返回的响应超过的 512 字节(UDP 最大只支持 512 字节的数据)
- 区域传送(区域传送是主域名服务器向辅助域名服务器传送变化的那部分数据)
文件传输协议
FTP 使用 TCP 进行连接,它需要两个连接来传送一个文件:
- 控制连接:服务器打开端口号 21 等待客户端的连接,客户端主动建立连接后,使用这个连接将客户端的命令传送给服务器,并传回服务器的应答。
- 数据连接:用来传送一个文件数据。
根据数据连接是否是服务器端主动建立,FTP 有主动和被动两种模式:
主动模式:服务器端主动建立数据连接,其中服务器端的端口号为 20,客户端的端口号随机,但是必须大于 1024,因为 0~1023 是熟知端口号。
被动模式:客户端主动建立数据连接,其中客户端的端口号由客户端自己指定,服务器端的端口号随机。
主动模式要求客户端开放端口号给服务器端,需要去配置客户端的防火墙。被动模式只需要服务器端开放端口号即可,无需客户端配置防火墙。但是被动模式会导致服务器端的安全性减弱,因为开放了过多的端口号。
动态主机配置协议
DHCP (Dynamic Host Configuration Protocol) 提供了即插即用的连网方式,用户不再需要手动配置 IP 地址等信息。
DHCP 配置的内容不仅是 IP 地址,还包括子网掩码、网关 IP 地址。
DHCP 工作过程如下:
- 客户端发送 Discover 报文,该报文的目的地址为 255.255.255.255:67,源地址为 0.0.0.0:68,被放入
UDP 中,该报文被广播到同一个子网的所有主机上。如果客户端和 DHCP 服务器不在同一个子网,就需要使用中继代理。 - DHCP 服务器收到 Discover 报文之后,发送 Offer 报文给客户端,该报文包含了客户端所需要的信息。因为客户端可能收到多个DHCP 服务器提供的信息,因此客户端需要进行选择。
- 如果客户端选择了某个 DHCP 服务器提供的信息,那么就发送 Request 报文给该 DHCP 服务器。
- DHCP 服务器发送 Ack 报文,表示客户端此时可以使用提供给它的信息。
常用端口
Web页面请求的过程
DHCP配置主机信息(获取源ip)
- 假设主机最开始没有 IP 地址以及其它信息,那么就需要先使用 DHCP 来获取。
- 主机生成一个 DHCP (动态主机配置协议)请求报文,并将这个报文放入具有目的端口 67 和源端口 68 的 UDP 报文段中。
- 该报文段则被放入在一个具有广播 IP 目的地址(255.255.255.255) 和源 IP 地址(0.0.0.0)的 IP 数据报中。
- 该数据报则被放置在 MAC 帧中,该帧具有目的地址 FF:FF:FF:FF:FF:FF,将广播到与交换机连接的所有设备。
- 连接在交换机的 DHCP 服务器收到广播帧之后,不断地向上分解得到 IP 数据报、UDP 报文段、DHCP 请求报文,之后生成 DHCP ACK 报文,该报文包含以下信息:IP 地址、DNS 服务器的 IP 地址、默认网关路由器的 IP 地址和子网掩码。该报文被放入 UDP 报文段中,UDP 报文段有被放入 IP 数据报中,最后放入 MAC 帧中。
- 该帧的目的地址是请求主机的 MAC 地址,因为交换机具有自学习能力,之前主机发送了广播帧之后就记录了 MAC地址到其转发接口的交换表项,因此现在交换机就可以直接知道应该向哪个接口发送该帧。
- 主机收到该帧后,不断分解得到 DHCP 报文。之后就配置它的 IP 地址、子网掩码和 DNS 服务器的 IP 地址,并在其 IP转发表中安装默认网关。
ARP解析Mac地址(查找默认网关路由器的MAC地址)
- 主机通过浏览器生成一个 TCP 套接字,套接字向 HTTP 服务器发送 HTTP 请求。为了生成该套接字,主机需要知道网站的域名对应的 IP 地址。
- 主机生成一个 DNS 查询报文,该报文具有 53 号端口,因为 DNS 服务器的端口号是 53。
- 该 DNS 查询报文被放入目的地址为 DNS 服务器 IP 地址的 IP 数据报中。
- 该 IP 数据报被放入一个以太网帧中,该帧将发送到网关路由器。
- DHCP 过程只知道网关路由器的 IP 地址,为了获取网关路由器的 MAC 地址,需要使用 ARP 协议。
- 主机生成一个包含目的地址为网关路由器 IP 地址的 ARP 查询报文,将该 ARP
- 查询报文放入一个具有广播目的地址(FF:FF:FF:FF:FF:FF)的以太网帧中,并向交换机发送该以太网帧,交换机将该帧转发给所有的连接设备,包括网关路由器。
- 网关路由器接收到该帧后,不断向上分解得到 ARP 报文,发现其中的 IP 地址与其接口的 IP 地址匹配,因此就发送一个 ARP回答报文,包含了它的 MAC 地址,发回给主机。
DNS域名解析(离开局域网去DNS服务器查目的域名的IP)
- 知道了网关路由器的 MAC 地址之后,就可以继续 DNS 的解析过程了。
- 网关路由器接收到包含 DNS 查询报文的以太网帧后,抽取出 IP 数据报,并根据转发表决定该 IP 数据报应该转发的路由器。
- 因为路由器具有内部网关协议(RIP、OSPF)和外部网关协议(BGP)这两种路由选择协议,因此路由表中已经配置了网关路由器到达 DNS 服务器的路由表项。
- 到达 DNS 服务器之后,DNS 服务器抽取出 DNS 查询报文,并在 DNS 数据库中查找待解析的域名。
- 找到 DNS 记录之后,发送 DNS 回答报文,将该回答报文放入 UDP 报文段中,然后放入 IP数据报中,通过路由器反向转发回网关路由器,并经过以太网交换机到达主机。
HTTP请求页面
- 有了 HTTP 服务器的 IP 地址之后,主机就能够生成 TCP 套接字,该套接字将用于向 Web 服务器发送 HTTP GET 报文。
- 在生成 TCP 套接字之前,必须先与 HTTP 服务器进行三次握手来建立连接。生成一个具有目的端口 80 的 TCP SYN 报文段,并向HTTP 服务器发送该报文段。
- HTTP 服务器收到该报文段之后,生成 TCP SYN ACK 报文段,发回给主机。
- 连接建立之后,浏览器生成 HTTP GET 报文,并交付给 HTTP 服务器。
- HTTP 服务器从 TCP 套接字读取 HTTP GET 报文,生成一个 HTTP 响应报文,将 Web页面内容放入报文主体中,发回给主机。
- 浏览器收到 HTTP 响应报文后,抽取出 Web 页面内容,之后进行渲染,显示 Web 页面。
HTTP
基础概念
请求和响应报文
客户端发送一个请求报文给服务器,服务器根据请求报文中的信息进行处理,并将处理结果放入响应报文中返回给客户端。
请求报文结构:
- 第一行是包含了请求方法、URL、协议版本;
- 接下来的多行都是请求首部 Header,每个首部都有一个首部名称,以及对应的值。
- 一个空行用来分隔首部和内容主体 Body
- 最后是请求的内容主体
响应报文结构:
- 第一行包含协议版本、状态码以及描述,最常见的是 200 OK 表示请求成功了
- 接下来多行也是首部内容
- 一个空行分隔首部和内容主体
- 最后是响应的内容主体
URL
HTTP 使用 URL( U niform Resource Locator,统一资源定位符)来定位资源,它是 URI(Uniform Resource Identifier,统一资源标识符)的子集,URL 在 URI 的基础上增加了定位能力。URI 除了包含 URL,还包含 URN(Uniform Resource Name,统一资源名称),它只是用来定义一个资源的名称,并不具备定位该资源的能力。例如 urn:isbn:0451450523 用来定义一个书籍名称,但是却没有表示怎么找到这本书。
HTTP方法
客户端发送的 请求报文 第一行为请求行,包含了方法字段。
GET
- 获取资源
- 当前网络请求中,绝大部分使用的是 GET 方法。
HEAD
- 获取报文首部
- 和 GET 方法类似,但是不返回报文实体主体部分。
- 主要用于确认 URL 的有效性以及资源更新的日期时间等。
POST
- 传输实体主体
- POST 主要用来传输数据,而 GET 主要用来获取资源。
PUT
- 上传文件
- 由于自身不带验证机制,任何人都可以上传文件,因此存在安全性问题,一般不使用该方法。
PATCH
- 对资源进行部分修改
- PUT 也可以用于修改资源,但是只能完全替代原始资源,PATCH 允许部分修改。
DELETE - 删除文件
- 与 PUT 功能相反,并且同样不带验证机制。
OPTIONS - 查询支持的方法
- 查询指定的 URL 能够支持的方法。
- 会返回 Allow: GET, POST, HEAD, OPTIONS 这样的内容。
GET和POST比较
GET 用于获取资源,而 POST 用于传输实体主体。
参数
GET 和 POST 的请求都能使用额外的参数,但是 GET 的参数是以查询字符串出现在 URL 中,而 POST 的参数存储在实体主体中。不能因为 POST 参数存储在实体主体中就认为它的安全性更高,因为照样可以通过一些抓包工具(Fiddler)查看。
因为 URL 只支持 ASCII 码,因此 GET 的参数中如果存在中文等字符就需要先进行编码。例如 中文 会转换为 %E4%B8%AD%E6%96%87,而空格会转换为 %20。POST 参数支持标准字符集。
安全
安全的 HTTP 方法不会改变服务器状态,也就是说它只是可读的。
GET 方法是安全的,而 POST 却不是,因为 POST 的目的是传送实体主体内容,这个内容可能是用户上传的表单数据,上传成功之后,服务器可能把这个数据存储到数据库中,因此状态也就发生了改变。
安全的方法除了 GET 之外还有:HEAD、OPTIONS。
不安全的方法除了 POST 之外还有 PUT、DELETE。
幂等性
幂等的 HTTP 方法,同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说就是,幂等方法不应该具有副作用(统计用途除外)。
所有的安全方法也都是幂等的。
在正确实现的条件下,GET,HEAD,PUT 和 DELETE 等方法都是幂等的,而 POST 方法不是。
GET /pageX HTTP/1.1 是幂等的,连续调用多次,客户端接收到的结果都是一样的:
POST /add_row HTTP/1.1 不是幂等的,如果调用多次,就会增加多行记录:
DELETE /idX/delete HTTP/1.1 是幂等的,即使不同的请求接收到的状态码不一样:
HTTP状态码
服务器返回的 响应报文 中第一行为状态行,包含了状态码以及原因短语,用来告知客户端请求的结果。
1XX 信息
100 Continue :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。
2XX 成功
- 200 OK
- 204 No Content:请求已经成功处理,但是返回的响应报文不包含实体的body部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。
- 206 Partial Content :表示客户端进行了范围请求,响应报文包含由 Content-Range 指定范围的实体内容。
3XX 重定向
-
301 Moved Permanently :永久性重定向
-
302 Found :临时性重定向
-
303 See Other :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源。
-
注:虽然 HTTP 协议规定 301、302 状态下重定向时不允许把 POST 方法改成 GET 方法,但是大多数浏览器都会在301、302 和 303 状态下的重定向把 POST 方法改成 GET 方法。
-
304 Not Modified:如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不满足条件,则服务器会返回304 状态码。
-
307 Temporary Redirect :临时重定向,与 302 的含义类似,但是 307 要求浏览器不会把重定向请求的 POST方法改成 GET 方法。
4XX 客户端错误
-
400 Bad Request :请求报文中存在语法错误。
-
401 Unauthorized :该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST
认证)。如果之前已进行过一次请求,则表示用户认证失败。 -
403 Forbidden :请求被拒绝。
-
404 Not Found
5XX 服务器错误
-
500 Internal Server Error :服务器正在执行请求时发生错误。
-
503 Service Unavailable :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
HTTP首部
有 4 种类型的首部字段:
- 通用首部字段
- 请求首部字段
- 响应首部字段
- 实体首部字段
各种首部字段及其含义如下
通用首部字段
请求首部字段
响应首部字段
实体首部字段
短连接与长连接
多次HTTP通信能否服用同一个链接
当浏览器访问一个包含多张图片的 HTML 页面时,除了请求访问的 HTML 页面资源,还会请求图片资源。如果每进行一次 HTTP 通信就要新建一个 TCP 连接,那么开销会很大。
长连接只需要建立一次 TCP 连接就能进行多次 HTTP 通信。
从 HTTP/1.1 开始默认是长连接的,如果要断开连接,需要由客户端或者服务器端提出断开,使用 Connection : close;
在 HTTP/1.1 之前默认是短连接的,如果需要使用长连接,则使用 Connection : Keep-Alive。
流水线
默认情况下,HTTP 请求是按顺序发出的,下一个请求只有在当前请求收到响应之后才会被发出。由于受到网络延迟和带宽的限制,在下一个请求被发送到服务器之前,可能需要等待很长时间。
流水线是在同一条长连接上连续发出请求,而不用等待响应返回,这样可以减少延迟
Cookie
HTTP 协议是无状态的,主要是为了让 HTTP 协议尽可能简单,使得它能够处理大量事务。HTTP/1.1 引入 Cookie 来保存状态信息。
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。由于之后每次请求都会需要携带 Cookie 数据,因此会带来额外的性能开销(尤其是在移动环境下)。
Cookie 曾一度用于客户端数据的存储,因为当时并没有其它合适的存储办法而作为唯一的存储手段,但现在随着现代浏览器开始支持各种各样的存储方式,Cookie 渐渐被淘汰。新的浏览器 API 已经允许开发者直接将数据存储到本地,如使用 Web storage API(本地存储和会话存储)或 IndexedDB。
用途:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
创建过程
服务器发送的响应报文包含 Set-Cookie 首部字段,客户端得到响应报文后把 Cookie 内容保存到浏览器中。
客户端之后对同一个服务器发送请求时,会从浏览器中取出 Cookie 信息并通过 Cookie 请求首部字段发送给服务器。
分类
- 会话期 Cookie:浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。
- 持久性 Cookie:指定过期时间(Expires)或有效期(max-age)之后就成为了持久性的 Cookie。
Secure
标记为Secure的Cookie只能通过被HTTPS协议加密过的请求发送给服务器。但即使设置了Secure标记,敏感信息也不应该通过Cookie传输,因为Cookie有其固有的不安全性,Secure标记也无法确保安全保保障
Session
除了可以将用户信息通过 Cookie 存储在用户浏览器中,也可以利用 Session 存储在服务器端,存储在服务器端的信息更加安全。
Session可以存储在服务器上的文件,数据库或者内存中。也可以将Session存储在Redis这种内存数据库中,效率会更好
使用Session维护登陆状态
- 用户进行登录时,用户提交包含用户名和密码的表单,放入HTTP请求报文中
- 服务器验证该用户名和密码,如果正确把用户信息存储到Redis中,他在Redis中的key称为Session ID
- 服务器返回的响应 报文的Set-Cookie首部字段包含了这个Session ID,客户端收到响应报文中之后将该Cookie值存放到浏览器中
- 客户端之后对同一个服务器进行请求时都会包含这个Cookie值,服务器收到之后取出Session
ID,从Redis中取出用户信息,继续之前的业务操作
应该注意Session ID的安全性问题,不能让它被恶意攻击或者轻易获取,那么就不能产生一个容易的Session ID,此外,还需要经常重新生成Session ID。在对安全性要求极高的场景下,例如,转账操作,除了使用Session管理用户状态,还需要对用户进行重新验证,比如重新输入密码,或者使用短信验证码的方式
浏览器禁用Cookie
此时无法使用Cookie保存用户信息,只能用Session。除此之外,不能将Session ID存放到Cookie中,而是使用URL重写技术,将Session ID作为URL的参数进行传递
Cookie与Session的选择
安全性,容量,性能
Cookie 只能存储 ASCII 码字符串,而 Session 则可以存储任何类型的数据,因此在考虑数据复杂性时首选 Session;
Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加密,然后在服务器进行解密;
对于大型网站,如果用户所有的信息都存储在 Session 中,那么开销是非常大的,因此不建议将所有的用户信息都存储到 Session 中。
通信数据转发
代理服务器接受客户端的请求,并且转发给其它服务器。
使用代理的主要目的是:
- 缓存
- 负载均衡
- 网络访问控制
- 访问日志记录
代理分为正向代理和反向代理
用户察觉得到正向代理的存在
反向代理一般位于内部网络,用户察觉不到
网关
与代理服务器不同的是,网关服务器会将 HTTP 转化为其它协议进行通信,从而请求其它非 HTTP 服务器的服务。
隧道
使用 SSL 等加密手段,在客户端和服务器之间建立一条安全的通信线路。
HTTPS
HTTP 有以下安全性问题:
- 使用明文进行通信,内容可能会被窃听;
- 不验证通信方的身份,通信方的身份有可能遭遇伪装;
- 无法证明报文的完整性,报文有可能遭篡改。
HTTPS 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer)通信,再由 SSL 和 TCP 通信,也就是说 HTTPS 使用了隧道进行通信。
通过使用 SSL,HTTPS 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。
加密类型
非对称加密
非对称密钥加密,又称公开密钥加密(Public-Key Encryption),加密和解密使用不同的密钥。
公开密钥所有人都可以获得,通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信内容后使用私有密钥解密。
非对称密钥除了用来加密,还可以用来进行签名。因为私有密钥无法被其他人获取,因此通信发送方使用其私有密钥进行签名,通信接收方使用发送方的公开密钥对签名进行解密,就能判断这个签名是否正确。
优点:可以更安全地将公开密钥传输给通信发送方;
缺点:运算速度慢。
HTTPS采用的加密方式
上面提到对称密钥加密方式的传输效率更高,但是无法安全地将密钥 Secret Key 传输给通信方。而非对称密钥加密方式可以保证传输的安全性,因此我们可以利用非对称密钥加密方式将 Secret Key 传输给通信方。HTTPS 采用混合的加密机制,正是利用了上面提到的方案:
- 使用非对称密钥加密方式,传输对称密钥加密方式所需要的 Secret Key,从而保证安全性;
- 获取到 Secret Key 后,再使用对称密钥加密方式进行通信,从而保证效率。(下图中的 Session Key 就是 Secret Key)
认证
通过使用证书来对通信双方进行验证
数字证书认证机构(CA,Certificate Authority)是客户端与服务器双方都可信赖的第三方机构。
既然是身份证,证书当然包含如颁发机构,有效期限,使用者等详细信息了。
证书具体包括的内容如下:
- 证书版本号(Version Number):规范的版本号,目前为版本3,值为0x2;
- 序列号(Serial Number):由CA维护的为它所发的每个证书分配的一个序列号,用来追踪和撤销证书。只要拥有签发者信息和序列号,就可以唯一标识一个证书;
- 签名算法(Signature Algorithm):该数字证书支持数字签名所采用的算法,如:sha256RSA。
- 颁发者(Issuer):就是CA颁发机构,是签发证书单位的标识信息。
- 有效期(Validity): 证书的有效期很,包括起止时间。
- 使用者(Subject): 证书拥有者的标识信息。如果使用的是OV或EV型证书,就可查看到企业信息,辨别公司真伪。
- 主体的公钥信息(Subject Public Key Info):所保护的公钥相关的信息。
- 使用者可选名称(Subject Alternative Name):即该证书保护的所有域名名称。
服务器的运营人员向CA提出公开密钥的申请,CA在判明提出申请者的身份后,会对已申请的公开密钥做数字签名,然后分配这个已经签名的公开密钥,并将公开密钥放入公开密钥证书后绑定在一起
- 签名
- 公钥
- hash算法
进行 HTTPS 通信时,服务器会把证书发送给客户端。客户端取得其中的公开密钥之后,先使用数字签名进行验证,如果验证通过,就可以开始通信了。
完整性保护
- SSL 提供报文摘要功能来进行完整性保护。
- HTTP 也提供了 MD5 报文摘要功能,但不是安全的。例如报文内容被篡改之后,同时重新计算 MD5
的值,通信接收方是无法意识到发生了篡改。 - HTTPS的报文摘要功能之所以安全,是因为它结合了加密和认证这两个操作。试想一下,加密之后的报文,遭到篡改之后,也很难重新计算报文摘要,因为无法轻易获取明文。
HTTPS的缺点
- 因为需要进行加密解密等过程,因此速度会更慢;
- 需要支付证书授权的高额费用。
HTTP2.0
HTTP/1.X的缺陷
- 客户端需要使用多个连接才能实现并发和缩短延迟;
- 不会压缩请求和响应首部,从而导致不必要的网络流量;
- 不支持有效的资源优先级,致使底层 TCP 连接的利用率低下
与HTTP1.1的差异
同HTTP/1.0协议,HTTP/2.0在TCP层(或者TLS层,如果有)和HTTP层之间添加一层二进制分帧层(Binary Framing Layer),将HTTP报文分为更小的Headers帧(对应HTTP/1.0报文的起始行和首部)和DATA帧(对应HTTP/1.0报文主体部分),然后进行二进制编码发送给对端
HTTP1.1基于文本传输,HTTP2.0基于二进制传输
HTTP2.0的大致结构如下
二进制分帧层
HTTP/2.0 将报文分成 HEADERS 帧和 DATA 帧,它们都是二进制格式的。
在通信过程中,只会有一个 TCP 连接存在,它承载了任意数量的双向数据流(Stream)。
- stream是一条抽象意义的双向字节流,建立在TCP连接之上。一条TCP连接可以有多条stream,每条stream可以传输一个或者多个message
- message可以类比HTTP/1.0协议的一条请求报文(或者响应报文),由frame组成(Headers Frame和DATA Frame,通过Type字段标识)。属于同一个message的帧必须要按指定顺序发送,然后到对端按照Stream Identifier(流标志符)进行组合,多个message的帧可以交错发送
- 帧(Frame)是最小的通信单位,来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重新组装,通过Flags可以标志流的结束。
服务端推送
HTTP/2.0 在客户端请求一个资源时,会把相关的资源一起发送给客户端,客户端就不需要再次发起请求了。例如客户端请求 page.html 页面,服务端就把 script.js 和 style.css 等与之相关的资源一起发给客户端。
首部压缩
- HTTP/1.1 的首部带有大量信息,而且每次都要重复发送。
- HTTP/2.0 要求客户端和服务器同时维护和更新一个包含之前见过的首部字段表,从而避免了重复传输。
- 不仅如此,HTTP/2.0 也使用 Huffman 编码对首部字段进行压缩。
优点
HTTP/2.0的优点除了降低了通信时延,另一方面使C/S通信不再局限于HTTP/1.0的一发一收模式,同时有效地解决了HTTP/1.1的管道化连接带来的响应报文队首阻塞问题(注:这里的队首阻塞仅是指HTTP层)
客户端可以发送多个message请求,服务端在获取所有的message请求后返回message响应(对应gRPC中的客户端流模式);客户端发送单个message请求,服务端接收处理后,可以返回多个message响应(对应gRPC中的服务端流模式);客户端也可以每发送一个message请求,服务端接受处理后就返回一个message响应(对应gRPC中的双向流模式)
总结
- HTTP/2采用二进制格式而非文本格式
- HTTP/2是完全多路复用的,而非有序并阻塞的——只需一个连接即可实现并行
- 使用报头压缩,HTTP/2降低了开销
- HTTP/2让服务器可以将响应主动“推送”到客户端缓存中
1.多路复用和二进制帧
HTTP/1.x 有个问题叫线端阻塞(head-of-line blocking), 它是指一个连接(connection)一次只提交一个请求的效率比较高, 多了就会变慢。 HTTP/1.1 试过用流水线(pipelining)来解决这个问题, 但是效果并不理想(数据量较大或者速度较慢的响应, 会阻碍排在他后面的请求). 此外, 由于网络媒介(intermediary )和服务器不能很好的支持流水线, 导致部署起来困难重重。而多路传输(Multiplexing)能很好的解决这些问题, 因为它能同时处理多个消息的请求和响应; 甚至可以在传输过程中将一个消息跟另外一个掺杂在一起。所以客户端只需要一个连接就能加载一个页面。
2.首部压缩
在 HTTP/1 中,HTTP 请求和响应都是由「状态行、请求 / 响应头部、消息主体」三部分组成。一般而言,消息主体都会经过 gzip 压缩,或者本身传输的就是压缩过后的二进制文件(例如图片、音频),但状态行和头部却没有经过任何压缩,直接以纯文本传输。
随着 Web 功能越来越复杂,每个页面产生的请求数也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输 UserAgent、Cookie 这类不会频繁变动的内容,完全是一种浪费。
3.HTTP2支持服务器推送
服务端推送是一种在客户端请求之前发送数据的机制。当代网页使用了许多资源:HTML、样式表、脚本、图片等等。在HTTP/1.x中这些资源每一个都必须明确地请求。这可能是一个很慢的过程。浏览器从获取HTML开始,然后在它解析和评估页面的时候,增量地获取更多的资源。因为服务器必须等待浏览器做每一个请求,网络经常是空闲的和未充分使用的。
为了改善延迟,HTTP/2引入了server push,它允许服务端推送资源给浏览器,在浏览器明确地请求之前。一个服务器经常知道一个页面需要很多附加资源,在它响应浏览器第一个请求的时候,可以开始推送这些资源。这允许服务端去完全充分地利用一个可能空闲的网络,改善页面加载时间