【Linux内核一】在Linux系统下网口数据收发包的具体流向是什么?

news2024/10/3 2:15:24

        在TCP/IP网络分层模型里,整个协议栈被分成了物理层、链路层、网络层,传输层和应用层。物理层对应的是网卡和网线,应用层对应的是我们常见的Nginx,FTP等等各种应用。Linux实现的是链路层、网络层和传输层这三层。

        在Linux内核实现中,链路层协议靠网卡驱动来实现,内核协议栈来实现网络层和传输层。内核对更上层的应用层提供socket接口来供用户进程访问。我们用Linux的视角来看到的TCP/IP网络分层模型应该是下面这个样子的。

        在了解网络收包过程之前,先了解一下网络收包过程的一些概念:

        1、硬中断+软中断:当设备上有数据到达的时候,会给CPU的相关引脚上触发一个电压变化(就是硬中断引脚),以通知CPU来处理数据。对于网络模块来说,由于处理过程比较复杂和耗时,如果在中断函数中完成所有的处理,将会导致中断处理函数(优先级过高)将过度占据CPU,将导致CPU无法响应其它设备,例如鼠标和键盘的消息。因此Linux中断处理函数是分上半部和下半部的。上半部是只进行最简单的工作,快速处理然后释放CPU,接着CPU就可以允许其它中断进来。剩下将绝大部分的工作都放到下半部中,可以慢慢从容处理。2.4以后的内核版本采用的下半部实现方式是软中断,由ksoftirqd内核线程全权处理。和硬中断不同的是,硬中断是通过给CPU物理引脚施加电压变化,而软中断是通过给内存中的一个变量的二进制值以通知软中断处理程序。

        2、ring buffer:ring buffer称作环形缓冲区,也称作环形队列(circular queue),是一种用于表示一个固定尺寸、头尾相连的缓冲区的数据结构,适合缓存数据流。如下为环形缓冲区(ring buffer) 的概念示意图。

        任务间的通信是ring buffer的典型应用场景。如进程A发数据,进程B取数据去处理,两个进程通常不可能无缝衔接,即进程B取数据的时机和进程A发数据的时机不能完全衔接上,所以需要一个缓存来做缓冲。具体应用有串口数据收发、log缓存、网卡处理网络数据包、音频/视频流处理等。在网络数据收发处理中,ring buffer位于网卡和内核协议栈之间,在物理上就是主机内存里的一块区域,另外ring buffer虽然名字叫buffer,但其本身不存储数据,实际上是个队列,队列里存放的是描述符,描述符描述的是存放数据包的内存地址,这个指定的地址就是socket buffer,下面讲。

        ring buffer有两个主要作用:

        a、可以平滑生产者(数据来源)和消费者(处理数据)的速度。

        b、通过 NAPI 的机制(就是硬中断加软中断,当网卡数据DMAring buffer的指定位置后,网卡会向CPU发出硬中断,这个硬中断处理函数没干别的,就只发出软中断请求,然后在软中断处理函数中调用poll函数将ring buffer指定的数据取到内核协议栈里,在此过程中硬中断是关闭的,数据取完了再打开硬中断),合并以减少 IRQ 次数。

    ring buffer,一篇文章讲透它? - 知乎 (zhihu.com),此文有ringbuffer的详细描述,这里只说个基本概念。

        3、socket buffer:Ring Buffer 队列内存放的是一个个 Packet 描述符,其有两种状态:ready和used。初始时描述符是空的,指向一个空的socket buffer,处在ready状态。当有数据时,DMA负责从 NIC 取数据,并在Ring Buffer 上按顺序找到下一个ready的描述符,将数据存入该 描述符指向的socket buffer中,并标记槽为 used。在此过程中,根据数据类型的不同,数据会被加上各种包头信息,封装成socket buffer指定的数据结构。当应用程序调用 read 系统调用时,程序会切换到内核区,并且会把 socket 接收缓冲区中的数据拷贝到用户区,拷贝后的数据会从 socket 缓冲区中移除。socket buffer可以看做是用户空间和内核空间的接口,同时也是网卡和内核之间的接口。Socket Buffer的设计优点是避免了重复拷贝数据,在发送和接收的分别都只有两次,分别是应用层和内核空间之间的拷贝、网卡的硬件缓冲区和内核空间之间的拷贝。

        有了以上的基本概念后,下面给出一个收包的基本流程:

        1.当收到报文时,网卡把数据包写入它自身的内存。

        2. 网卡通过CRC校验检查数据包是否有效,之后调用DMA把数据包发送到主机的内存缓冲区,这是驱动程序提前向内核申请好的一块内存区域,就是ring buffer指向的socket buffer空间。

        3.数据包的实际大小、checksum和其他信息会保存在独立的Ring Buffer(Rx.ring)中,Ring Buffer接收之后,NIC 会向主机发出中断,告知内核有新的数据到达。收到中断,驱动会把数据包包装成指定的数据结构(sk_buff)并发送到上一层。

        4.链路层会检查数据包是否有效并且解析出上层的协议(网络协议)。

        5.IP 层同样会检查数据包是否有效。检查IP checksum。

        6.TCP层检查数据包是否有效。检查 TCP checksum。

        7.如果是TCP报文,内核会根据TCP控制块中的端口号信息,找到对应的 socket,数据会被增加到socke的接收缓冲区,socket接收缓冲区的大小就是 TCP 接收窗口。Udp报文同理,不同的是TCP的发送和接收都有socket buffer,udp只有接收端有。

        8.当应用程序调用 read 系统调用时,程序会切换到内核区,并且会把 socket 接收缓冲区中的数据拷贝到用户区,拷贝后的数据会从 socket 缓冲区中移除。

        如下两图:

 

 

    以上参考自:简述 Linux I/O 原理及零拷贝(下) — 网络 I/O_Linux_Qunar技术沙龙_InfoQ写作社区

    发包过程基本就是相反流程,具体可以查看以上链接。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/397400.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux(Centos)安装Minio集群

目录1:简介2:功能与集成3:架构4:搭建集群4.1:挂载磁盘4.1.1:要求4.1.2:创建挂载目录4.1.3:注意:需要将新建的目录挂在到对应的磁盘下,磁盘不挂载好,集群启动会…

Tomcat 并发达太大导致系统崩溃解决方案

当 Tomcat 并发达太大导致系统崩溃时,可以通过以下几个步骤来解决这个问题: 1、分析原因 首先需要分析系统崩溃的原因,是因为Tomcat的性能瓶颈还是因为代码的Bug,或者是系统资源不足等等。 2、优化代码 如果是代码的问题&…

Unity Lighting -- 为场景烘焙lightmap

烘焙光照是什么? Unity中有两种不同的光照方式:实时光照和烘焙光照。 实时光照 Unity会在运行时实时计算光照。实时光源每一帧都会进行计算,这意味着它们对于场景中移动的角色和物体的响应性非常好,但它的开销也很大。 烘焙光照…

DJ1-3 操作系统引论

目录 操作系统的结构设计 1. 无结构操作系统 2. 模块化 OS 结构 3. 分层式 OS 结构 4. 微内核 OS 结构 操作系统的结构设计 操作系统是一个大型系统软件,其结构已经历了四代的变革: 第一代 OS 是无结构第二代 OS 采用模块式结构第三代是层次式结构…

韩国绿芯1~16通道触摸芯片型号推荐

随着技术的发展,触摸感应技术正日益受到更多关注和应用,目前实现触摸感应的方式主要有两种,一种是电阻式,另一种是电容式。电容式触摸具有感应灵敏、功耗低、寿命长等特点,因此逐步取代电阻式触摸,成为当前…

炫龙游戏本Win10系统总是蓝屏崩溃怎么办?

炫龙游戏本Win10系统总是蓝屏崩溃怎么办?有用户使用的炫龙游戏本最近总是在运行的过程中出现自动蓝屏的情况,有的时候自己还在操作电脑,而屏幕却蓝屏了,导致自己的工作被中断了。那么这个情况要怎么去进行修复呢?来看看…

关于centos虚拟机设置固定ip、设置后无法上网、宿主机无法ping通的解决方案

一.centos设置固定ip 1.虚拟机设置 编辑→虚拟网络编辑器,选择NAT模式。 2.NAT设置,设置网关(前面三个需要与你设置的静态虚拟机ip一致(我的是192.168.2.40))。 3.虚拟机设置为NAT模式 4.设置虚拟…

数据结构2——线性表1:基本概念

1、线性表的概念 线性表是具有相同特性的数据元素的一个有限序列。就像用细线串珠子,一个接着一个串起来。 2、线性表的逻辑特征 ① 在非空的线性表中有且只有一个开始结点a1,他没有直接前驱,而仅有一个直接后继a2,相当于a1是…

关于JS中this对象指向问题总结

一、前言 关于JS中this对象指向问题,相信做过项目的小伙伴多多少少都会遇到过,明明感觉代码写的没问题,可是运行的时候,就会报错,比如报错 xxx is not a function。 我最近也遇到了,百度学习了不少前辈对于…

Codeforces Round 703 (Div. 2)(A~D)

A. Shifting Stacks给出一个数组,每次可以将一个位置-1,右侧相邻位置1,判断是否可以经过若干次操作后使得数列严格递增。思路:对于每个位置,前缀和必须都大于该位置应该有的最少数字,即第一个位置最少是0&a…

Vue 2 组件发布到 npm

本教程使用官网教程中指示的 Rollup 作为打包工具,并尽量遵循官网教程的指引进行实践;组件项目的初始化创建方式亦是使用官网提倡的 Vue CLI 工具简便生成。另外组件打包发布到 npm 还可以使用 webpack 作为打包工具,但不在本文讨论范围。 前…

YOLOv5s网络模型讲解(一看就会)

文章目录前言1、YOLOv5s-6.0组成2、YOLOv5s网络介绍2.1、参数解析2.2、YOLOv5s.yaml2.3、YOLOv5s网络结构图3、附件3.1、yolov5s.yaml 解析表3.2、 yolov5l.yaml 解析表总结前言 最近在重构YOLOv5代码,本章主要介绍YOLOv5s的网络结构 1、YOLOv5s-6.0组成 我们熟知YO…

openFoam中cellZone的使用及编程

简介 通常在流体计算中需要对某个特定区域进行处理(比如添加源项,可参考这篇文章OpenFOAM编程:VOF法与多孔介质模型相结合),这是就需要用到cellZone. 通常有两种产生cellZone的方式: (1)从其他划分网格的…

一文带你看透通用文字识别 OCR

什么是 OCR? OCR技术指的是 Optical Character Recognition 或光学文字识别技术,即从图像中识别文字,并将其转换为电子文本或机器可读格式。它可以被广泛应用于图像处理,文字处理,自然语言处理,计算机视觉…

Kubernetes学习(五)持久化存储

Volume 卷 容器中的文件在磁盘上是临时存放的,这给容器中运行的特殊应用带来了一些问题。首先,当容器崩溃时,kubectl将重新启动容器,容器中的文件将会丢失--应为容器会以干净的状态重建。其次,当在一个Pod中运行多个容…

【算法题目】【Python】彻底刷遍DFS/BFS的算法题目

文章目录参考资料树的前序、中序、后序遍历树的层次遍历回溯与剪枝组合组合总和 III电话号码的字母组合组合总和组合总和 II参考资料 参考这里面的一些讲解: https://github.com/youngyangyang04/leetcode-master。 树的前序、中序、后序遍历 看完 树的种类 之后…

网络 | UDP与TCP协议讲解 | TCP可靠性是怎样实现的?

文章目录前置知识查看网络状态的工具查看进程idUDP协议协议格式UDP只有接收缓冲区基于UDP的应用层协议TCP协议流的理解协议格式确认应答机制缓冲区序号的作用流量控制超时重传机制6位标志位紧急数据的处理三次握手listen的第二个参数全连接和半连接队列都维护了什么信息&#x…

史上最全若依管理系统修改页面标题和logo

整理若依框架去除 若依标题、logo及其他内容。一:网页上的logo进入ruoyi-ui --> public --> favicon.ico,把这个图片换成你自己的logo二:页面中的logo进入ruoyi-ui --> src --> assets --> logo --> logo.png,把…

Git版本控制工具(详解)

Git版本控制工具 Git常见命令速查表 集中式版本控制 cvs和svn都是属于集中式版本控制系统 他们的主要特点是单一的集中管理服务器 保存所有文件的修订版本协同开发人员通过客户端连接到这台服务器 取出最新的文件或者提交更新 优点每个人都可以在一定程度上看到项目中的其他…

动态规划——子序列、编辑距离、回文子串

目录 子序列问题 300.最长递增子序列 674.最长连续递增序列 718.最长重复子数组 1143.最长公共子序列 1035.不相交的线 53.最大子序和 编辑距离 392.判断子序列 115.不同的子序列 583.两个字符串的删除操作 72.编辑距离 回文子串 647.回文子串 516.最长回文子序列…