1、网络模型
1、OSI网络模型
开放式系统互联通信参考模型,简称 OSI网络模型
- 应用层:负责为应用程序提供统一的接口
- 表示层:负责把数据转换成兼容接收系统的格式
- 会话层:负责维护计算机之间的通信连接
- 传输层:负责为数据加上传输表头,形成数据包
- 网络层:负责数据的路由和转发
- 数据链路层:负责MAC寻址、错误侦测和改错
-
2、TCP/IP 网络模型
应用层:负责向用户提供一组应用程序,如 HTTP、FTP、DNS等
- 传输层:负责端到端的通信。比如 TCP、UDP等
- 网络层:负责网络包的封装、寻址和路由,比如 IP、ICMP等
网络接口层:负责网络包在物理网络中的传输,比如MAC寻址、错误侦测以及通过网卡传输网络帧等。
2、Linux网络栈
有了 TCP/IP 模型后,在进行网络传输时,数据包就会按照协议栈,对上一层发来的数据进行逐层处理;完后封装上该层的协议头,再发送给下一层。

传输层:增加了TCP头
- 网络层:增加了IP头
- 网络接口层:增加了帧头和帧尾
物理链路中不能传输随意大小的数据包。网络接口配置的最大传输单元(MTU),就规定了最大的IP包大小。常用的以太网中,MTU 默认值是 1500 。
Linux内核中的网络栈,也类似TCP/IP 的四层结构。
- 最上层应用程序:通过系统调用,来跟套接字接口进行交互
- 套接字下面:传输层、网络层和网络接口层
- 最底层:网卡驱动程序以及物理网卡设备。
网卡:是发送和接收网络包的基本设备。在系统启动过程中,网卡通过内核中的网卡驱动程序注册到系统中。而在网络手法过程中,内核通过中断跟网卡进行交互。
网卡硬中断只处理最核心的网卡数据读取或发送,而协议栈中的大部分逻辑,都会放到软中断中处理。
3、Linux网络收发流程
1、网络包接收流程
当一个网络帧达到网卡后,网卡会通过 DMA 的方式,把这个网络包放到收包队列中,然后通过硬中断,告诉中断处理程序已经收到了网络包。
接着,网卡中断处理程序会为网络帧分配内核数据结构(sk_buff),并将其拷贝到 sk_buff 缓冲区中;然后在通过软中断,通知内核收到了新的网络帧。
接下来,内核协议栈从缓冲区取出网络帧,并通过网络协议栈,从上到下逐层处理网络帧,如:
- 在链路层检查报文的合法性,找出上层协议的类型(如 IPV4 还是 IPV6),再去掉帧头、帧尾,然后交给网络层
- 网络层取出IP头,判断网络包的下一步走向,如 是交给上层处理还是转发。当网络层确认这个包是要发送到本机后,就会取出上层协议的类型(如:tcp还是udp),去掉 IP 头,再交给传输层处理
- 传输层取出 TCP头或UDP头之后,根据 < 源 IP、源端口、目的 IP、目的端口 > 四元组作为标识,找出对应的 Socket,并把数据拷贝到 Socket 的接收缓存中。
最后,应用程序就可以使用 Socket 接口,读取到新接收到的数据了。
2、网络包发送流程
首先,应用程序调用 Socket API (如 sendmsg)发送网络包。由于这是一个系统调用,所以会陷入到内核态的套接字层中。套接字层会把数据包放到 Socket 发送缓冲区中。
接下来,网络协议栈从 Socket 发送缓冲区中,取出数据包;再按照 TCP/IP 栈,从上到下逐层处理。比如,传输层和网络层,分别为其增加 TCP头 和IP 头,执行路由查找确认下一跳的IP,并按照 MTU 大小分片。
分片后的网络包,再送到网络接口层,进行物理地址寻址,以找到下一跳的 MAC 地址。然后添加帧头和帧尾,放到发包队列中。这一切完成后,会有软中断通知驱动程序:发包队列中有新的网络帧需要发送。最后,驱动程序通过 DMA ,从发包队列中读出网络帧,并通过物理网卡把它发送出去。
4、性能指标
- 带宽:表示链路的最大传输速度,单位常为 b/s(比特/秒)
- 吞吐量:表示单位时间内成功传输的数据量,单位常为 b/s(比特/秒)或者 B/s(字节/秒)。吞吐量受带宽限制,而 吞吐量/带宽,也就是该网络的使用率
- 延时:表示从网络请求发出后,一直到收到远端相应,所需要的时间延迟。如,建立连接需要的时间(TCP握手延时),一个数据包往返所需的时间(如RTT)
- PPS:是 Packet Per Second(包 / 秒)的缩写,表示以网络包为单位的传输速率。PPS 通常用来评估网络的转发能力,比如硬件交换机,通常可以达到线性转发(即 PPS 可以达到或者接近理论最大值)。
- 以及 网络的可用性(网络能否正常通信)、并发连接数(TCP 连接数量)、丢包率(丢包百分比)、重传率(重新传输的网络包比例)等
5、网络配置
以网络接口 ens33 为例,
- 网络接口的状态标志:ifconfig 输出的 RUNNING,或 ip 输出的 LOWER_UP,都表示物理网络是连通的,即网线在线
- MTU大小:默认是1500
- 网络接口的IP地址、子网以及MAC地址
- 网络收发的字节数、包数、错误数以及丢包情况。特别是 TX 和 RX 部分的 errors、dropped、overruns、carrier 以及 collisions 等指标不为 0 时,通常表示出现了网络 I/O 问题。其中:
- errors 表示发生错误的数据包数,比如校验错误、帧同步错误等
- dropped 表示丢弃的数据包数,即数据包已经收到了 Ring Buffer,但因为内存不足等原因丢包
- overruns 表示超限数据包数,即网络 I/O 速度过快,导致 Ring Buffer 中的数据包来不及处理(队列满)而导致的丢包
- carrier 表示发生 carrirer 错误的数据包数,比如双工模式不匹配、物理电缆出现问题等
-
6、套接字信息
# head -n 3 表示只显示前面3行# -l 表示只显示监听套接字# -n 表示显示数字地址和端口(而不是名字)# -p 表示显示进程信息netstat -nlp | head -n 3

# -l 表示只显示监听套接字 # -t 表示只显示 TCP 套接字 # -n 表示显示数字地址和端口(而不是名字) # -p 表示显示进程信息 ss -ltnp | head -n 3
当套接字处于连接状态(Established)时, Recv-Q:表示套接字缓冲还没有被应用程序取走的字节数(接收队列长度)
- Send-Q:表示还没有被远端主机确认的字节数(发送队列长度)
当套接字处于监听状态(Listening)时,
- Recv-Q:表示全连接队列的长度
- Send-Q:表示全连接队列的最大长度
1、全连接:就是完成TCP三次握手后,服务器就会把这个连接挪到全连接队列中。这些全连接中的套接字,会需要被 accept() 系统调走,服务器才能真正处理客户端的请求。
2、半连接:还没有完成TCP三次握手的连接。服务器收到了客户端的 SYN 包后,就会把这个连接放到半连接队列中,然后再向客户端发送 SYN + ACK包。
7、协议栈统计信息
8、网络吞吐和PPS
sar -n 查看网络的统计信息,如 网络接口(DEV)、网络接口错误(EDEV)、TCP、UDP、ICMP 等等
- rxpck/s 和 txpck/s 分别是接收和发送的 PPS,单位为包 / 秒。
- rxkB/s 和 txkB/s 分别是接收和发送的吞吐量,单位是 KB/ 秒。
- rxcmp/s 和 txcmp/s 分别是接收和发送的压缩数据包数,单位是包 / 秒。
- %ifutil 是网络接口的使用率,即半双工模式下为 (rxkB/s+txkB/s)/Bandwidth,而全双工模式下为 max(rxkB/s, txkB/s)/Bandwidth。
Bandwidth 可以用 ethtool 来查询,它的单位通常是 Gb/s 或者 Mb/s
9、连通性和延时
ping -c3 表示发送三次ICMP包后停止
每个 ICMP 请求的信息,包括 ICMP 序列号(icmp_seq)、TTL(生存时间,或者跳数)以及往返延时。

