当前位置: 首页 > news >正文

Linux 网络收包流程

哈喽大家好,我是咸鱼

我们在跟别人网上聊天的时候,有没有想过你发送的信息是怎么传到对方的电脑上的

又或者我们在上网冲浪的时候,有没有想过 HTML 页面是怎么显示在我们的电脑屏幕上的

无论是我们跟别人聊天还是上网冲浪,其实都依靠于计算机网络这项技术

计算机网络是指将多台计算机通过通信设备和传输介质连接在一起,使得它们之间能够相互通信、资源共享和协同工作

而计算机之间是通过数据包来实现信息传输和信息交换的,数据包是计算机网络中传输数据的基本单位

今天咸鱼将以 Linux 为例来给大家介绍一下 Linux 是如何实现网络接收数据包

网络协议栈&网络架构

在正文开始之前,我们先来了解一下 Linux 中的网络协议模型和网络子系统

  • 网络协议模型(网络协议栈)

在 Linux 中,Linux 网络协议栈分成了五层
在这里插入图片描述
其中:

  • 应用层提供 socket 接口来供用户进程访问内核空间的网络协议栈
  • 传输层、网络层协议由 Linux 内核网络协议栈实现
  • 链路层协议靠网卡驱动来实现
  • 物理层协议由硬件网卡实现

在这里插入图片描述

  • 网络子系统(网络架构)

网络子系统是 Linux 内核中的一部分,由多个模块和驱动程序组成,它负责管理和控制系统的网络功能以实现网络通信

通过 Linux 网络子系统(网络架构)来实现上述网络协议模型
在这里插入图片描述
其中

  • System call interface:为应用程序获取内核的网络系统提供了接口,例如 socket
  • Protocol agnostic interface:为和各种传输层协议的网络交互提供的一层公共接口
  • Network protocals:对各种传输层协议的实现,如 TCP、UDP、IP 等
  • Device agnostic interface:为各种底层网络设备抽象出的公共接口,与各种网络设备驱动连接在一起
  • Device drivers:与各种网络设备交互的驱动

收包过程

当 Linux 接收一个数据包的时候,这个包是怎么经过 Linux 的内核从而被应用程序拿到的呢?
在这里插入图片描述

  • 到达网卡(NIC,Network Interface Card)

首先数据包到达网卡之后,网卡会校验接收到的数据包中的目的 MAC 地址是不是自己的 MAC 地址,如果不是的话通常就会丢弃掉

这种只接受发送给自己的数据包(其余的扔掉)的工作模式称为非混杂模式(Non-Promiscuous Mode)

**混杂模式(Promiscuous Mode)**则是网卡会接收通过网络传输的所有数据包,而不仅仅是发送给它自己的数据包

非混杂模式是网卡默认的工作模式,可以尽可能的保护网络安全和减少网络负载

网卡在校验完 MAC 地址之后还会校验数据帧(Data Frame)中校验字段 FCS 来一次确保接收到的数据包是正确的

  • 网卡硬件缓冲区 ——> 系统内存(ring buffer)

当网卡接收到数据包时,它将数据包的内容存储在硬件缓冲区中,然后通过 DMA 将接收到的数据从硬件缓冲区传输到系统内存中的指定位置,这个位置通常是一个环形缓冲区( ring buffer)

DMA(直接内存访问,Direct Memory Access)

DMA是一种数据传输技术,允许外设(如网卡、硬盘控制器、显卡等)直接访问计算机内存,而无需经过 CPU

通过 DMA 可以大大提高数据传输的效率,减轻 CPU 的负担

  • 触发硬中断

当网卡将数据包 DMA 到用于接收的环形缓冲区(rx_ring)之后,就会触发一个硬中断来告诉 CPU 数据包收到了

什么时候会触发一个硬中断,可以通过下面的参数来进行配置:

  • rx-usecs:当过这么长时间过后,一个中断就会被产生
  • rx-frames:当累计接收到这么多个数据帧后,一个中断就会被产生

上面的参数配置可以通过下面的命令来查看

# 以 CentOS 7 为例
ethtool -c <网卡名称>

当 ring buffer 满了之后,新来的数据包将给丢弃

ifconfig 查看网卡的时候,可以里面有个 overruns,表示因为环形队列满而被丢弃的包

CPU 收到硬中断之后就会停止手中的活,保存上下文,然后去调用网卡驱动注册的硬中断处理函数

为数据包分配 skb_buff ,并将接收到的数据拷贝到 skb_buff 缓冲区中

当一个数据包经过了网卡引起中断之后,每一个包都会在内存中分配一块区域,称为 sk_buff (套接字缓存,socket buffer )

sk_buff 是 Linux 网络的一个核心数据结构

  • 触发软中断

网卡的硬中断处理函数处理完之后驱动先 disable 硬中断,然后 enable 软中断

ps:待 ring buffer 中的所有数据包被处理完成后,enable 网卡的硬中断,这样下次网卡再收到数据的时候就会通知 CPU

内核负责软中断进程 ksoftirqd 发现有软中断请求到来,进行下面的一些操作

# 查看软中断进程
[root@localhost ~]# ps -ef | grep ksoftirqd

调用 net_rx_action 函数

它会通过 poll 函数去 rx_ring 中拿数据帧,获取的时候顺便把 rx_ring 上的数据给删除

static void net_rx_action(struct softirq_action *h)
{struct softnet_data *sd = &__get_cpu_var(softnet_data);unsigned long time_limit = jiffies + 2;int budget = netdev_budget;void *have;local_irq_disable();while (!list_empty(&sd->poll_list)) {......n = list_first_entry(&sd->poll_list, struct napi_struct, poll_list);work = 0;if (test_bit(NAPI_STATE_SCHED, &n->state)) {work = n->poll(n, weight);trace_napi_poll(n);}budget -= work;}
}

除此之外,poll 函数会把 ring buffer 中的数据包转换成内核网络模块能够识别的 skb 格式(即 socket kernel buffer

socket kernel buffer (skb) 是 Linux 内核网络栈处理网络包(packets)所使用的 buffer,它的类型是 sk_buffer

3、最后进入 netif _receive_skb 处理流程,它是数据链路层接收数据帧的最后一关

根据注册在全局数组 ptype_allptype_base 里的网络层数据帧类型去调用第三层协议的接收函数处理

例如对于 ip 包来讲,就会进入到 ip_rcv;如果是 arp 包的话,会进入到 arp_rcv

  • 到达网络层(以 IP 协议为例)

IP 层的入口函数在 ip_rcv 函数,调用 ip_rcv 函数进入三层协议栈

首先会对数据包进行各种检查(检查 IP Header),然后调用 netfilter 中的钩子函数: NF_INET_PRE_ROUTING

netfilter: 是 Linux 内核中进行数据包过滤,连接跟踪(Connect Track),网络地址转换(NAT)等功能的主要实现框架

该框架在网络协议栈处理数据包的关键流程中定义了一系列钩子点(Hook 点),并在这些钩子点中注册一系列函数对数据包进行处理

这些注册在钩子点的函数即为设置在网络协议栈内的数据包通行策略,也就意味着,这些函数可以决定内核是接受还是丢弃某个数据包

NF_INET_PRE_ROUTING 会根据预设的规则对数据包进行判断并根据判断结果做相关的处理(修改或者丢弃数据包)

处理完成后,数据包交由 ip_rcv_finish 处理,该函数根据路由判决结果,决定数据包是交由本机上层应用处理,还是需要进行转发

如果是交由本机处理,则会交由 ip_local_deliver 本地上交流程;如果需要转发,则交由 ip_forward 函数走转发流程

  • 到达传输层(以 TCP 为例)

传输层 TCP 处理入口在 tcp_v4_rcv 函数,首先检查数据包的 TCP 头部等信息,确保数据包的完整性和正确性

然后去查找该数据包对应的已经打开的 socket ,如果找不到匹配的 socket,表示该数据包不属于任何一个已建立的连接,因此该数据包会被丢弃

如果找到了匹配的 socket,TCP 会进一步检查该 socket 和连接的状态,如果状态正常,TCP 会将数据包从内核传输到用户空间,放入 socket 的接收缓冲区(socket receive buffer)

  • 应用层获取数据

当数据包到达操作系统内核的传输层时,应用程序可以从套接字的接收缓冲区(socket receive buffer)中读取数据包

一般有两种方式读取数据,一种是 recvfrom 函数阻塞在那里等着数据来,这种情况下当 socket 收到通知后,recvfrom 就会被唤醒,然后读取接收队列的数据

另一种是通过 epoll 或者 select 监听相应的 socket,当收到通知后,再调用 recvfrom 函数去读取接收队列的数据

总结

网络模块可以说是 Linux 内核中最复杂的模块了

看起来一个简简单单的收包过程就涉及到许多内核组件之间的交互,如网卡驱动、协议栈,内核ksoftirqd 线程等

咸鱼原本打算把收包和发包的流程都写上的,但是光是写收包流程就就要了我半条命了,等下次有机会把发包的流程也写一下

总结一下 Linux 网络收包流程:

  • 数据到达网卡之后,网卡通过 DMA 将数据放到内存分配好的一块 ring buffer 中,然后触发硬中断
  • CPU 收到硬中断之后简单的处理了一下(分配 skb_buffer),然后触发软中断
  • 软中断进程 ksoftirqd 执行一系列操作(例如把数据帧从 ring ruffer上取下来)然后将数据送到三层协议栈中
  • 在三层协议栈中数据被进一步处理发送到四层协议栈
  • 在四层协议栈中,数据会从内核拷贝到用户空间,供应用程序读取
  • 最后被处在应用层的应用程序去读取

相关文章:

Linux 网络收包流程

哈喽大家好&#xff0c;我是咸鱼 我们在跟别人网上聊天的时候&#xff0c;有没有想过你发送的信息是怎么传到对方的电脑上的 又或者我们在上网冲浪的时候&#xff0c;有没有想过 HTML 页面是怎么显示在我们的电脑屏幕上的 无论是我们跟别人聊天还是上网冲浪&#xff0c;其实…...

flex: 0 0 273px的意思

flex: 0 0 273px; 是一条CSS属性&#xff0c;用于设置flexible box布局&#xff08;flexbox&#xff09;中的flex子项的灵活性和尺寸。 这条属性包含三个值&#xff0c;分别是&#xff1a; flex-grow: 表示弹性增长因子&#xff0c;指定当有多余空间时&#xff0c;子项能够增长…...

helm部署rabbitmq

1.添加rabbitmq仓库并下载包 helm repo add bitnami https://charts.bitnami.com/bitnami helm pull bitnami/rabbitmq --version 10.1.4 tar -zxvf rabbitmq-10.1.4.tgz mv values.yaml values.yaml.back grep -v "#" values.yaml.back > values.yaml2.helm部署…...

Java版Spring Cloud+Spring Boot+Mybatis+uniapp知识付费平台讲解

提供私有化部署&#xff0c;免费售后&#xff0c;专业技术指导&#xff0c;支持PC、APP、H5、小程序多终端同步&#xff0c;支持二次开发定制&#xff0c;源码交付。 Java版知识付费-轻松拥有知识付费平台 多种直播形式&#xff0c;全面满足直播场景需求 公开课、小班课、独…...

编程之舞:流程控制乐章

流程控制语句 1. 复合语句 2. 条件语句2.1 if条件语句2.2 switch多分支语句 3. 循环语句3.1 while循环语句3.2 do...while循环语句3.3 for循环语句 4. 循环控制4.1 break语句4.2 continue语句 5. 实践与练习 1. 复合语句 复合语句是由一对花括号括起来的语句块&#xff0c;可以…...

ChatGPT是否能够进行情感融合和语气调整?

ChatGPT是一种预训练的通用语言模型&#xff0c;具有很强的文本生成和理解能力。在情感融合和语气调整方面&#xff0c;ChatGPT可以通过特定的技术和训练方法实现一定程度的情感表达和语气调整。下面将详细探讨ChatGPT在情感融合和语气调整方面的应用方法和潜力。 1. **情感融…...

C++--动态规划路径问题

1.不同路径 力扣 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从…...

从实践彻底掌握MySQL的主从复制

目录 一、本次所用结构如图---一主多从级联&#xff1a; 二、IP。 三、配置M1&#xff1a; 四、从库M1S1&#xff1a; 五、从库M2配置&#xff1a; 六、 从库M2S1&#xff1a; 一、本次所用结构如图--- 一主多从级联&#xff1a; 二、IP。这里M1S1和M1S2一样的&#xff0…...

机器学习深度学习——线性回归的基本元素

回归用来表示输入输出之间的关系。 用实际例子来解释一下线性回归&#xff1a;根据房屋的面积、房龄来估算房屋价格。为了实现这个预测放假的模型&#xff0c;需要收集一个真实的数据集&#xff0c;该数据集包括了房屋的销售价格、面积和房龄。 在机器学习中&#xff0c;这个数…...

K8S初级入门系列之八-网络

一、前言 本章节我们将了解K8S的相关网络概念&#xff0c;包括K8S的网络通讯原理&#xff0c;以及Service以及相关的概念&#xff0c;包括Endpoint&#xff0c;EndpointSlice&#xff0c;Headless service&#xff0c;Ingress等。 二、网络通讯原理和实现 同一K8S集群&…...

分段@Transactional 坑及失效问题

Transactional 背景&#xff1a;在某些情况下&#xff0c;我们需要分段transaction&#xff0c;在最外面没有transaction&#xff0c;里面分成几个transaction&#xff0c;保证分段是成功的。 问题代码&#xff1a; Service public Order getOrder1(String id) {Optional<Or…...

25、matlab里面的10中优化方法介绍——Opt_Golden法(matlab程序)

1.简述 基本思想 黄金分割法也称为 0.618 法&#xff0c;其基本思想是通过取试探点和进行函数值比较&#xff0c;使包含极小点的搜索区间不断缩短以逼近极小值点。适用于确定区间上的任何单谷函数求极小值的问题。 公式推导 设有定义在[ a , b ] [a,b][a,b]上的单谷函数 φ ( …...

点云拟合球体

前言&#xff1a;在很多情况下&#xff0c;需要根据点云来拟合球体&#xff0c;本博文主要介绍各种方法的拟合情况及优缺点&#xff0c;希望对各位小伙伴有所帮助&#xff01; 目录 1. vtkFitImplicitFunction进行球拟合 2. 四点求解球 1. vtkFitImplicitFunction进行球拟合 …...

基于动态规划(DP)算法的增程式EV能量管理策略研究(MATLAB编程)

文章目录 算法代码仿真结果结果分析算法代码 clc; clear; close all; load CWTVC.mat N=length(T_z); %N=200;load minFuelConsup.txt minFuel_Pe=minFuelConsup(:...

前端知识点视频补充

使用工具&#xff1a; Vscode使用&#xff1a; 需要下载插件&#xff1a;open in browser。这个插件可以快速打开浏览器。 选择文件夹有两种方式&#xff1a;选择打开文件、拖拽方式&#xff08;这种最方便&#xff09; 快捷键&#xff1a;快速生成Htm结构文件&#xff1a;…...

python多线程—终止子线程

总体思路 1、获取需要终止的子线程id 2、根据子线程id&#xff0c;终止子线程。 过程 获取子线程id&#xff1a; import threading Thread_id threading.get_ident() # 获取子线程的id值线程终止函数 def async_raise(Thread_id, exctype):"""raises th…...

#P1012. [NOIP2015提高组] 神奇的幻方

题目描述 幻方是一种很神奇的 N \times NNN 矩阵&#xff1a;它由数字 1,2,3, \ldots ,N \times N1,2,3,…,NN 构成&#xff0c;且每行、每列及两条对角线上的数字之和都相同。 当 NN 为奇数时&#xff0c;我们可以通过以下方法构建一个幻方&#xff1a; 首先将 11 写在第一行…...

(学习笔记-IP)Ping的工作原理

Ping是基于ICMP协议工作的&#xff0c;ICMP报文封装在IP包里面&#xff0c;它工作在网络层&#xff0c;是IP协议的助手。 ICMP包头的类型字段&#xff0c;大致可分为两大类&#xff1a; 一类是用于诊断的查询消息&#xff0c;也就是查询报文类型一类是通知出错原因的错误消息&…...

php 进程间通信:管道、uds

1、管道 1.1、管道概念 管道是单向的、先进先出的&#xff0c;它把进程的输出和另一个进程的输入连接在一起。一个进程往管道写入数据&#xff0c;另一个进程从管道读取数据。数据被从管道中读取出来之后&#xff0c;将被删除&#xff0c;其他进程无法在读取到相应的数据。管…...

Stable Diffusion如何生成高质量的图-prompt写法介绍

文章目录 Stable Diffusion使用尝试下效果prompt的编写技巧prompt 和 negative promptPrompt格式Prompt规则细节优化Guidance Scale 总结 Stable Diffusion Stable Diffusion是一个开源的图像生成AI系统,由Anthropic公司开发。它基于 Transformer模型架构,可以通过文字描述生成…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...