本章主要介绍 TCP/IP 协议中,数据包处理的主要流程。首先我们介绍一些前置信息,然后描述整个接收过程。
注:本章内容主要来自公众号“开发内功修炼”的?络篇。
前置知识
术语
项 | 说明 | 用户态 | 只能执行机器的部分指令,使用全部指令集的一个子集。能影响机器的控制指令或者是 I/O 操作指令,在用户态都是不被允许的。 | 内核态 | 内核态具有对硬件的完全访问权,可以执行机器能够执行的任何指令。 | 系统调用 | 为了使用户进程使用内核功能,内核会暴露出一些接口以供他们使用。这些接口是用户进程使用内核功能的唯一手段。用户进程使用这些接口的行为称为系统调用。 | socket | 是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在 Internet 上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个 Socket,并绑定到一个端口上,不同的端口对应于不同的服务。 | socket 接收队列 | 需要被接收的数据的队列。 | socket 等待队列 | 等待数据的对象(进程)队列。 | ringbuffer | 保存网卡数据的循环缓冲区。 | 硬中断 | 由与系统相连的外设(比如网卡、硬盘)自动产生的。主要是用来通知操作系统系统外设状态的变化。比如当网卡收到数据包的时候,就会发出一个中断。我们通常所说的中断指的是硬中断。 | 软中断 | 为了满足实时系统的要求,中断处理应该是越快越好。linux为了实现这个特点,当中断发生的时候,硬中断处理那些短时间就可以完成的工作,而将那些处理事件比较长的工作,放到中断之后来完成,也就是软中断(softirq)来完成。 | 网卡 | 在这里只需要理解成一个设备,用于发送和接收网络数据。 | DMA | 设备可以自己执行读或者写总线事务而不需要 CPU 干涉的过程,称成为直接内存访问。 |
内核态用户态推荐阅读:
https://cloud.tencent.com/developer/article/1376540?from=14588
https://cloud.tencent.com/developer/article/1683403?from=14588
TPC/IP ?协议栈
下图是 TPC/IP 五层模型中,各层作用的介绍,具体的信息,可以 Google 或者百度。
启动初始化
在系统启动的过程中,系统会进行许多初始化程序。例如:
- 注册硬中断处理程序
- 软中断softirq程序的创建与初始化
- 协议栈注册(ip、tpc、udp...)
- 网卡驱动初始化与启动。
- ...
数据接收过程
?
?
- 用户进程创建s ocket (默认正常建立 TCP 连接),系统调用 recvform,查看socket对象的接收队列中查看是否有数据,如果没有就把自己添加到 scoket 对应的等待队列里,最后让出CPU。
- 当数据到达网卡时,通过 DMA 将数据写入 ringbuffer,然后发起硬中断,通知 CPU。
- 硬中断处理函数几乎没做什么,就发起软中断。
- 内核程序 ksoftirqd 线程发现软中断请求到来,关闭硬中断,并调用程序接收 ringbuffer 数据包,并打包成 skb,发送到对应的 socket 接收队列。
- ksoftirqd 唤醒用户进程。
- 用户进程唤醒等待队列中的对象处理数据。
- 通过层层协议栈的处理(IP、TPC...),最终将数据发送到用户进程。
参考
? ? ?1.公众号“开发内功修炼”的?络篇
|