1. 基础
1.1 计算机网络体系结构
1.2 OSI 模型
开放式系统互联模型(Open System Interconnection Model,简称为 OSI 模型)是一种概念模型,由国际标准化组织提出,并试图成为计算机在世界范围内互连为网络的标准框架,它具有七层网络结构。
1.3 五层模型
- 应用层 :为特定应用程序提供数据传输服务,例如 HTTP、DNS 等协议。数据单位为报文。
- 传输层 :为进程提供通用数据传输服务。由于应用层协议很多,定义通用的传输层协议就可以支持不断增多的应用层协议。 传输层包括两种协议:
- 传输控制协议 TCP,提供面向连接、可靠的数据传输服务,数据单位为报文段;
- 用户数据报协议 UDP,提供无连接、尽最大努力的数据传输服务,数据单位为用户数据报。TCP 主要提供完整性服务,UDP 主要提供及时性服务。
- 网络层 :为主机提供数据传输服务。而传输层协议是为主机中的进程提供数据传输服务。网络层把传输层传递下来的报文段或者用户数据报封装成分组。
- 数据链路层 :网络层针对的还是主机之间的数据传输服务,而主机之间可以有很多链路,链路层协议就是为同一链路的主机提供数据传输服务。数据链路层把网络层传下来的分组封装成帧。
- 物理层 :考虑的是怎样在传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。
1.4 TCP/IP 模型
应用层
- 为用户提供应用功能;如 HTTP、FTP、Telnet等
- 工作于操作系统的用户态
传输层
传输层包含两个协议:
- TCP (Transmission Control Protocol,传输控制协议)
- UDP (User Datagram Protocol,用户数据报协议 )
端口:用于识别和区分数据发送的目标
网络层
网络层主要包含两个协议:
- ARP协议;用于映射 IP 和 MAC 地址
- IP 协议
IP 协议会将传输层的报文作为数据部分,再加上 IP 包头组装成 IP 报文,如果 IP 报文大小超过 MTU(以太网中一般为 1500 字节)就会再次进行分片,得到一个即将发送到网络的 IP 报文。
IP 地址分为:
- 网络号,标识 IP 地址属于哪个子网
- 主机号,标识子网中的主机
网络号和主机号通过子网掩码计算,子网掩码可用 IP 格式或用1的位数标表示(如:255.255.255.0
或 /24
):
- 网络号,IP 地址和掩码按位与得到;如:
10.100.122.2 & 255.255.255.0 = 10.100.120.0
- 主机号,IP 地址和掩码取反后按位与;如:
10.100.122.2 & 0.0.0.255 = 0.0.0.2
IP 路由寻址
路由器寻址工作中,就是要找到目标地址的子网,找到后进而把数据包转发给对应的网络内。
网络接口层
生成了 IP 头部之后,接下来要交给网络接口层(Link Layer)在 IP 头部的前面加上 MAC 头部,并封装成数据帧(Data frame)发送到网络上。
MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息,可以通过 ARP 协议获取对方的 MAC 地址。
网络接口层主要为网络层提供「链路级别」传输的服务,负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标识网络上的设备
小结
TCP/IP 网络通常是由上到下分成 4 层,分别是应用层,传输层,网络层和网络接口层。
每层报文封装格式:
- 网络接口层的传输单位是 帧(frame)
- IP 层的传输单位是 包(packet)
- TCP 传输单位是 段(segment)
- HTTP 传输单位是 报文(message)
1.5 浏览器键入网址到显示网页期间发生了什么
HTTP
第一步,解析 URL
第二步,生成 HTTP 请求
DNS
第三步,查询服务器 IP 地址
通过域名访问 DNS 服务器解析出 IP 地址。
DNS 层级关系如下:
- 根 DNS 服务器(.)
- 顶级域名 DNS 服务器
- 权威 DNS 服务器
域名解析流程
- 客户端发送 DNS 请求给本地 DNS 服务器(本地网络设置的 DNS 服务器地址)
- 本地DNS服务器若存在缓存则直接返回;若没有则访问根 DNS 服务器
- 根DNS服务器根据域名返回顶级域名DNS服务器的地址
- 本地DNS服务器访问顶级域名DNS服务器,获取权威域名DNS服务器地址
- 本地DNS服务器访问权威域名DNS服务器,获取域名对应的 IP 地址
- 将 IP 地址返回给客户端
缓存
解析域名,无需每次经过完整流程,会优先在缓存中寻找:
- 浏览器缓存
- 操作系统缓存,即 HOSTS 文件
- DNS 服务器自身的缓存
协议栈
应用程序(浏览器)通过调用 Socket 库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责收发数据的 TCP 和 UDP 协议,这两个传输协议会接受应用层的委托执行收发数据的操作。
协议栈的下面一半是用 IP 协议控制网络包收发操作,在互联网上传数据时,数据会被切分成一块块的网络包,而将网络包发送给对方的操作就是由 IP 负责的。
此外 IP 中还包括 ICMP
协议和 ARP
协议。
ICMP
用于告知网络包传送过程中产生的错误以及各种控制信息。ARP
用于根据 IP 地址查询相应的以太网 MAC 地址。
IP 下面的网卡驱动程序负责控制网卡硬件,而最下面的网卡则负责完成实际的收发操作,也就是对网线中的信号执行发送和接收操作。
TCP
第四步,决定传输协议 TCP
HTTP 是基于 TCP 协议的,所以采用 TCP 进行传输。
TCP 报文头
- 源端口号和目标端口号:用于表示发送源和发送目标
- 序号:用于解决包乱序的问题,接收方会在缓存区中按照序号排序
- 确认号:用于确认接收方是否收到,若未收到的重新发送,用于解决丢包问题
- 数据偏移:占 4 位,其所能表达的最大数字是 15 。数据偏移表示该数据报中数据的起始位置,由于数据报是由 首部+数据 组成,所以实际上就是指报文段的首部长度。数据偏移的单位是 32 位字(即以 4 字节长为单位),所以数据偏移的最大长度是 60 (15*4)字节,即 TCP 报文段的首部长度不能超过 60 字节,对应的选项长度不能超过 40 字节。
- 保留:占 6 位,保留为今后使用,目前应置为 0
- 控制位:
- 紧急 URG (URGent):当值为 1 时,表明紧急指针字段有效,代表此报文中有紧急数据,应尽快传送,而无需按原来的排队顺序传送。
- 确认 ACK (ACKnowledgment):当值为 1 时,确认号有效;值为 0 时,确认号无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置为 1。
- 推送 PSH (Push):当值为 1 时,表示接受方应该将数据立即交付给应用进程,而不是等待缓存填满后再向上交付。
- 复位 RST (Reset):当值为 1 时,表明 TCP 连接出现严重差错,必须立即释放,然后再重新建立连接;也可以用来拒绝一个非法的报文段或拒绝打开一个连接。
- 同步 SYN (SYNchronization):在连接建立时用来同步序号。当 SYN = 1 而 ACK = 0 时,表明这是一个连接请求报文段;对方若同意建立连接,则应在响应的报文段中使 SYN = 1 和 ACK = 1 。
- 终止 FIN (FINis):当值为 1 时,表明此报文段发送方的数据已发送完毕,并要求释放连接。
- 窗口:占 2 字节,取值范围为 [ 0 , 216 - 1 ] 之间的整数。窗口字段保持动态变化,用于指明接收方允许发送方发送的数据量。
- 校验和:占 2 字节,校验的字段范围包括首部和数据
- 紧急指针:占 2 字节,仅在 URG = 1 时才有意义,用于指明紧急数据的结束位置,位于结束位置之后的就是普通数据
- 选项:长度可变,最长可达 40 字节。可用的选项有:最大报文段长度 ,窗口扩大选项、时间戳选项等
建立连接-三次握手
- 服务器主动监听端口,进入 LISTEN 状态
- 客户端发起连接,同步位
SYN = 1
,选择初始序列号seq = x
,进入SYN-SENT
同步已发送状态 - 服务端若同意接收请求,则发送确认报文,同步位和确认位置 1(
SYN = 1, ACK = 1
),确认号ack = x + 1
,选择初始序列号seq = y
,进入SYN-RCVD
同步已接收状态 - 客户端收到报文后,发送确认报文,确认位
ACK = 1
,确认号ack = y + 1
,序列号seq = x + 1
。进入已连接状态ESTABLISHED
- 服务端收到报文,进入已连接状态
ESTABLISHED
三次握手的目的
用于确认双方的报文收发功能正常。
数据分割
如果 HTTP 请求消息比较长,超过了 MSS
的长度,这时 TCP 就需要把 HTTP 的数据拆解成一块块的数据发送,而不是一次性发送所有数据。
MTU
:一个网络包的最大长度,以太网中一般为1500
字节。MSS
:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度。
数据会被以 MSS
的长度为单位进行拆分,拆分出来的每一块数据都会被放进单独的网络包中。也就是在每个被拆分的数据加上 TCP 头信息,然后交给 IP 模块来发送数据。
生成 TCP 报文
IP
TCP 报文后续会被封装成 IP 报文进行发送。
- 源地址 IP :发送方的 IP 地址
- 目标地址 IP:接收方的 IP 地址;在 DNS 域名解析阶段获取的服务器 IP
- 协议号:
06
表示 TCP 协议
生成 IP 报文
MAC
生成 IP 报文之后,需要添加 MAC 头部:
- 发送方 MAC 地址:MAC 地址是在网卡生产时写入到 ROM 里的,只要将这个值读取出来写入到 MAC 头部就可以了。
- 接收方目标 MAC 地址:通过 ARP 协议查询路由表获取 IP 地址对应的 MAC 地址
- 协议类型:当前报文采用的协议
0800
:IP0806
:ARP
ARP
ARP 协议通过广播的形式,获取 IP 对应的 MAC 地址。
查询 MAC 地址流程:
- 查询 ARP 缓存
- 若缓存不存在,发送 ARP 广播查询,并将查询结果加入缓存
Linux 使用 arp -a
查询 ARP 缓存。
生成 MAC 报文
网卡
网卡将报文的二进制信息转化成电信号,进行发送。
网卡通过网卡驱动进行控制,网卡驱动获取网络包之后,会将其复制到网卡内的缓存区中,接着会在其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。
- 起始帧分界符是一个用来表示包起始位置的标记
- 末尾的
FCS
(帧校验序列)用来检查包传输过程是否有损坏
交换机
交换机的设计是将网络包原样转发到目的地。交换机工作在 MAC 层,也称为二层网络设备。
首先,电信号到达网线接口,交换机里的模块进行接收,接下来交换机里的模块将电信号转换为数字信号。
然后通过包末尾的
FCS
校验错误,如果没问题则放到缓冲区。这部分操作基本和计算机的网卡相同,但交换机的工作方式和网卡不同。
计算机的网卡本身具有 MAC 地址,并通过核对收到的包的接收方 MAC 地址判断是不是发给自己的,如果不是发给自己的则丢弃;相对地,交换机的端口不核对接收方 MAC 地址,而是直接接收所有的包并存放到缓冲区中。因此,和网卡不同,交换机的端口不具有 MAC 地址。
将包存入缓冲区后,接下来需要查询一下这个包的接收方 MAC 地址是否已经在 MAC 地址表中有记录了。
交换机的 MAC 地址表主要包含两个信息:
- 一个是设备的 MAC 地址,
- 另一个是该设备连接在交换机的哪个端口上。
若MAC表中没有指定的 MAC 地址时会如何
此时交换机会将包转发到除源端口的所有端口上,即发送广播:
- 若非目标设备,则会忽略此报文
- 若为目标设备,则做出响应,交换机此时将 MAC 地址写入地址表中
路由器
和交换机的区别
- 路由器是基于 IP 设计的,俗称三层网络设备,路由器的各个端口都具有 MAC 地址和 IP 地址;
- 交换机是基于以太网设计的,俗称二层网络设备,交换机的端口不具有 MAC 地址。
工作原理
当转发包时,首先路由器端口会接收发给自己的以太网包,然后路由表查询转发目标,再由相应的端口作为发送方将以太网包发送出去。
工作流程
- 接收数据包:
- 电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,然后通过包末尾的
FCS
进行错误校验 - 如果没问题则检查 MAC 头部中的接收方 MAC 地址,看看是不是发给自己的包,如果是就放到接收缓冲区中,否则就丢弃这个包。
- 电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,然后通过包末尾的
- 查询路由,确定输出端口:
- 去掉包开头的 MAC 头部;MAC 头部的作用就是将包送达路由器,其中的接收方 MAC 地址就是路由器端口的 MAC 地址。因此,当包到达路由器之后,MAC 头部的任务就完成了,于是 MAC 头部就会被丢弃。
- 获取报文中的 IP 头部
- 查询路由表,确当发送目标:
- 根据路由表的网关列判断对方的地址:
- 如果网关是一个 IP 地址,则这个IP 地址就是我们要转发到的目标地址,还未抵达终点,还需继续需要路由器转发。
- 如果网关为空,则 IP 头部中的接收方 IP 地址就是要转发到的目标地址,也是就终于找到 IP 包头里的目标地址了,说明已抵达终点。
- 根据 ARP 协议获取下个转发目的地的 MAC 地址,发送数据包;在网络包传输的过程中,源 IP 和目标 IP 始终是不会变的,一直变化的是 MAC 地址,因为需要 MAC 地址在以太网内进行两个设备之间的包传输。
服务器
服务器收到数据包后,将数据包进行层层解析:
最终应用层收到的就是客户端发送的 HTTP 请求报文。