一、网络缓冲区
- 在内核中也是有网络缓冲区的,比如使用
read
读取数据(read
是一种系统调用,第一个参数为fd
),当陷入到内核态的时候,会通过fd
指定socket
,socket
会找到对应的接收缓冲区。 - 在应用程序中设计缓冲区,通过一定的算法来组织好我们的网络数据,方便应用程序在处理业务逻辑的时候从缓冲区中获取数据,进行解析,展开相对应的业务逻辑。
二、Linux 如何接收发送网络数据
- 应用程序通过系统调用,由用户态陷入到内核态,在内核态中找到对应的
socket
。socket
层有对应的接收缓冲区和发送缓冲区。
- 根据具体的接口判断是
TCP
还是UDP
,如果是TCP
,就加上一些TCP
的处理,比如说加上TCP
头。 - 进入
IP
层。 - 进入
MAC
层,会加上一个MAC
头部信息(帧头帧尾)。 - 经过网卡驱动把数据写到一个环形缓冲区中,便于网卡从环形缓冲区中读取数据,然后把数据发送到网络中。
- 内核中读取数据是独立运行的,应用程序读取数据也是独立运行的。
- 如果应用层需要拿对端发送的数据,先需要通过系统调用陷入到内核态,然后把在
socket
层中的已经准备好的接收缓冲区中的数据拷贝到应用程序中。 - 两个流程:
- 网络协议栈从网络中把数据写到
socket
对应的的接收缓冲区。 - 应用程序通过系统调用从接收缓冲区中拷贝数据到应用层去处理。
- 网络协议栈从网络中把数据写到
- 网络数据
- 数据帧
frame
→ 网卡驱动、MAC
层。 - 数据包
packet
→IP
层。 - 数据段
segment
→TCP
/UDP
层。 data
→ 应用层。
- 数据帧
- 接收网络数据包的流程:
- 网卡接收到数据包,然后把数据写到
DMA
区域(ringbuffer
结构)。DMA
:Direct Memory Access
,直接内存操作,不需要CPU
参与。
- 网卡向
CPU
发起硬件中断,CPU
收到中断请求,根据中断表查找中断处理函数,调用中断处理函数。- 为什么需要硬件中断 ?
- 因为需要使用
CPU
将数据拷贝出来,然后在内核中进行处理。
- 因为需要使用
- 为什么需要硬件中断 ?
- 中断处理函数将屏蔽硬件中断,发起软件中断 → 让
CPU
参与将DMA
区域中的数据拷贝到网卡驱动,然后经过网络协议栈进行处理。- 为什么需要先屏蔽硬件中断 ?
- 避免
CPU
频繁被网卡中断。
- 避免
- 为什么需要软件中断 ?
- 使用软件中断处理耗时操作,避免执行时间过长,导致
CPU
没法响应其他硬件中断。
- 使用软件中断处理耗时操作,避免执行时间过长,导致
- 为什么需要先屏蔽硬件中断 ?
- 内核
ksoftirqd
线程负责软中断处理,该线程从ringbuffer
中逐个取出数据帧到sk_buff
。 - 从帧头取出
IP
协议,判断是IPv4
还是IPv6
,去掉帧头帧尾。 - 从
IP
头看上一层协议是TCP
还是UDP
,根据五元组找到socket
,并将数据提取出来放到socket
的接收缓冲区
- 网卡接收到数据包,然后把数据写到