国际标准化组织(ISO)制定了开放式系统互联通信参考模型(OSI模型),该模型分为七层,包括应用层、表示层、会话层、传输层、网络层、数据链路层和物理层
然而,由于OSI模型过于复杂,实际应用中更常用的是TCP/IP模型,它简化为四层:应用层、传输层、网络层和网络接口层
Linux系统正是基于TCP/IP模型来实现其网络协议栈的
一、TCP/IP模型概述 1.应用层:提供用户所需的各种服务,如HTTP、DNS、FTP等
2.传输层:提供端到端的通信功能,确保数据包的顺序传送及数据的完整性
主要协议有TCP和UDP
3.网络层:解决主机到主机的通信问题,负责数据包的路由、转发和分片
主要协议有IP、ICMP等
4.网络接口层:负责数据在主机和网络之间的交换,具体协议由参与互连的各网络自行定义
二、Linux网络协议栈 Linux网络协议栈类似于TCP/IP的四层结构
数据包的发送和接收都遵循这一结构,从用户态的应用程序到内核态的网络协议栈,再到硬件网卡,每一层都有其特定的职责和处理流程
三、Linux链路层发包流程 在Linux系统中,网络数据包的发送是一个复杂但有序的过程,涉及多个层次和组件的协同工作
以下是详细的发送流程: 1.应用程序调用Socket接口 发送过程始于应用程序调用Socket接口发送数据包的请求
这是一个系统调用,会从用户态陷入到内核态的套接字层
2.数据拷贝到内核态sk_buff 套接字层会申请一个内核态的sk_buff内存,将用户待发送的数据拷贝到sk_buff内存,并将其加入到Socket发送缓冲区等待网络协议栈的处理
3.协议栈逐层处理 网络协议栈从Socket发送缓冲区中取出数据包,然后按照TCP/IP协议栈的分层(传输层、网络层、网络接口层),从上到下逐层进行处理
-传输层:在传输层,会为数据包添加TCP头(如果使用TCP协议),同时拷贝一个新的sk_buff副本
这是因为sk_buff在到达网卡发送完成的时候会被释放掉,而TCP协议支持重传,为确保网络包可靠传输,在收到对方的ACK之前,这个sk_buff不能被删除
-网络层:在网络层,主要工作包括选取路由(确认下一跳的IP)、填充IP头、netfilter过滤、对超过MTU大小的数据包进行分片
处理完这些工作后会交给网络接口层处理
-网络接口层:网络接口层会进行物理地址寻址,以找到下一跳的MAC地址,填充帧头和帧尾,将其放到发送队列中
然后触发软中断告诉网卡驱动程序:队列中有新的网络包需要发送
4.驱动程序通过DMA发送数据 驱动程序收到通知会通过DMA(Direct Memory Access,直接内存访问),从发送包队列中读出网络帧,并通过DMA将数据写入网卡的FIFO(First In First Out,先进先出)发送队列
5.网卡设备发送数据包 网卡设备从FIFO发送队列中取出数据包,将其发送到网络
当发送完成的时候,网卡设备会触发一个硬中断来释放内存,主要是释放sk_buff内存和清理RingBuffer内存
6.传输层释放sk_buff 最