1. 应用程序调用发送相关的系统调用
- 应用程序调用
write()、send()、sendto()等系统调用 - 数据从用户空间复制到内核空间
- 系统调用进入内核态,开始网络包发送流程
2. Socket 层处理
- 根据 socket 类型(TCP/UDP)选择相应的传输层协议
- 创建初始的 sk_buff (socket buffer) 结构体,这是内核中网络数据包的表示形式
- 数据被放入 socket 的发送缓冲区
3. 传输层处理
对于 TCP 连接:
- 将数据分段,确保每段不超过 MSS (最大分段大小)
- 计算序列号、确认号等 TCP 头部信息
- 实施拥塞控制、流量控制算法
- 添加 TCP 头部到数据包
对于 UDP 连接:
- 简单地添加 UDP 头部
- 计算校验和
4. 网络层处理
- 路由查找,确定数据包下一跳的目的地
- 根据路由信息和 IP 协议添加 IP 头部
- 如果数据包超过 MTU (最大传输单元),进行分片
- 执行 netfilter 规则(iptables)
5. 网络设备层处理
- 添加数据链路层头部(如以太网头部,包含 MAC 地址)
- GSO (Generic Segmentation Offload) 可能会延迟分段,让网卡硬件来完成
- 调用网络设备的发送接口
6. 流量控制/排队规则 (QDisc)
- Linux 流量控制子系统 (tc) 对数据包进行排队和调度
- 根据配置的 QDisc (排队规则) 决定发送顺序和时机
- 常见排队规则:FIFO、SFQ (随机公平队列)、HTB (分层令牌桶) 等
- 可以实现带宽限制、优先级控制等高级网络功能
7. 网卡驱动处理
- 驱动程序将 sk_buff 转换为网卡理解的格式
- 填充 Ring Buffer 的描述符,指向内存中的数据包
- 通知网卡有新的数据包等待发送
8. DMA 传输到网卡
- 网卡通过 DMA (直接内存访问) 从内存中读取数据包
- 无需 CPU 参与,直接将数据从内存传输到网卡硬件
- 网卡可能在此阶段执行 TSO (TCP 分段卸载) 等硬件优化
9. 网卡发送过程
- 网卡完成最后的帧封装
- 将数字信号转换为电信号/光信号等物理形式
- 通过物理介质发送数据包到网络
10. 发送完成通知
- 网卡完成发送后,触发硬件中断
- 驱动程序处理中断,触发软中断通知传输层发送完成
- 对于 TCP 连接,更新拥塞窗口等状态信息
- 释放已发送的 sk_buff 结构

1012

被折叠的 条评论
为什么被折叠?



