linux 系统是如何收发数据包

news2024/11/13 9:07:59

目录

1. 背景

1.1 协议栈的构成

1. 应用层:

2. Socket 层:

3. 传输层 (TCP/UDP):

4. 网络层 (IP):

5. 数据链路层 (MAC):

6. 物理层 (网卡驱动):

1.2 数据包的组成

2. 接收网络数据包的流程

2.1 数据包接收流程概述

2.2 详细步骤说明

2.2.1 网卡接收数据包

2.2.2 触发硬件中断

2.2.3 处理硬件中断

2.2.4 软中断处理

2.2.5 协议解析与路由

2.2.6 数据分发到 Socket

2.2.7 应用程序处理

3. 发送网络数据包的流程(TCP)

3.1 数据包发送流程概述

3.2 详细步骤说明

3.2.1 应用程序发送数据

3.2.2 协议栈准备数据

3.2.3 协议封装

3.2.4 软中断通知网卡

3.2.5 网卡驱动发送数据

3.2.6 触发网卡发送

3.2.7 处理 ACK 应答

4. sk_buff 结构

5. 总结


1. 背景

1.1 协议栈的构成

想象一下,网络通信就像是一次邮寄包裹的过程,而 TCP/IP 协议栈就是这整个过程中的各个环节,每一层都有自己独特的职责,确保包裹能够安全、准确地送达目的地。具体来说,TCP/IP 协议栈主要分为以下几层:

1. 应用层:

这是你和网络互动的最上层,就像是你写信或包裹标签的地方。常见的应用包括浏览器、邮件客户端、文件传输工具等。

  • 应用程序(例如浏览器、文件传输程序)生成需要通过网络发送的数据。
  • 应用程序通过系统调用(如 send()recv()connect() 等)与操作系统交互,向下传递数据。这个系统调用通常会与套接字(socket)进行交互。
2. Socket 层:

想象这是邮局中的分拣部门,负责将你的包裹(数据)分发到正确的目的地。主要协议有 TCP(传输控制协议)和 UDP(用户数据报协议)。

  • 套接字作为操作系统提供的一种抽象接口,使应用程序能够与底层的网络协议栈交互。
  • 在套接字层,应用程序可以选择使用 TCPUDP 协议。TCP 是面向连接的,提供可靠的数据传输,保证数据按序到达;而 UDP 是无连接的,不保证数据的可靠传递。
3. 传输层 (TCP/UDP):

这层就像是国际物流公司,决定包裹的最佳运输路线。主要协议是 IP(互联网协议)。

  • TCP:当使用 TCP 协议时,传输层会对数据进行分段(segment),为每个段添加首部信息,包括序列号、确认号等,确保数据可靠传输。
  • UDP:当使用 UDP 协议时,数据会被打包成数据报(datagram),每个数据报包含源端口、目标端口、长度和校验和信息。UDP 的特点是简单、快速,但不保证数据的完整性或顺序。
4. 网络层 (IP):

类似于本地配送,负责在同一个网络内传递包裹,处理物理地址(MAC 地址)和局域网协议。

  • 传输层的数据会传递给网络层,IP 协议会将这些段或数据报封装进 IP 包中。IP 包含源地址和目的地址,用于确定数据包的路由。
  • IP 协议 不保证数据的传递,但它负责把数据包从源地址传送到目标地址。它通常与 ICMP(Internet Control Message Protocol)等协议一起使用,用于处理错误和诊断。
5. 数据链路层 (MAC):

这是实际运输包裹的物理媒介,比如道路、飞机、船只等。在网络中,这对应于网卡、光纤、电缆等。

  • 在网络层之后,数据被传递到数据链路层,也称为 MAC 层。此时,数据会被封装进帧(Frame),每一帧包含目标 MAC 地址、源 MAC 地址等信息。MAC 地址是用来标识网络接口的物理地址。
  • 数据链路层主要负责在局域网内传输数据,并将数据传递给正确的物理网络接口。
6. 物理层 (网卡驱动):
  • 数据帧最终被传递到物理层,也就是网卡驱动层。在这里,数据会通过网络接口卡(NIC)实际发出去,可能通过以太网、Wi-Fi 等介质传输到目的地。
  • 同样,接收到的数据包也会经过网卡驱动,上传至数据链路层、网络层,最终到达应用层。

1.2 数据包的组成

每当你发送或接收数据时,这些数据会在不同的层级被“打包”,每一层都会添加一些必要的信息,确保数据能够顺利传输。具体来说:

  • 用户层数据(User Data):就像你写在信封里的内容,是最原始的数据。
  • TCP 段(Segment):传输层会把用户数据分成小块(段),并添加一些控制信息,比如序列号,确保数据能按顺序到达。
  • IP 包(Packet):网络层会把这些段封装成 IP 包,添加源地址和目标地址,确保数据知道要去哪里。
  • 链路层帧(Frame):数据链路层会进一步封装成帧,添加源和目标的物理地址(MAC 地址),确保数据在局域网内能找到正确的设备。
  • sk_buff 结构:在 Linux 内核中,所有这些封装好的数据包都通过一个叫做 sk_buff 的结构来管理和传递。它就像是数据包的“行李标签”,包含了所有必要的信息和指针。

2. 接收网络数据包的流程

接收数据包的过程有点像快递员送货到你家,然后你拆开包裹检查内容。具体步骤如下:

2.1 数据包接收流程概述

  1. 网卡接收数据包:当数据包通过网络到达你的电脑时,网卡(Network Interface Card)就像是快递员,把包裹(数据)通过 DMA(直接内存访问)直接放到内存中的环形缓冲区(ring buffer)。
  2. 触发硬件中断:网卡发现有新包裹到达后,会向 CPU 发出一个“快递来了”的信号,这就是硬件中断。
  3. 处理硬件中断
    • 中断处理函数:CPU 收到中断信号后,会查找对应的处理程序,就像接到快递通知后去取包裹。
    • 屏蔽中断:为了防止连续不断的快递打扰,处理程序会暂时屏蔽同一来源的进一步中断。
    • 发起软中断:复杂的处理任务会交给软中断,就像让助手帮忙整理包裹,避免你被繁琐的任务耽误其他事情。
  4. 软中断处理
    • 内核 ksoftirqd 线程:这是内核中的一个专门线程,负责处理这些软中断。它会从环形缓冲区中取出一个个数据包,转换成 sk_buff 结构。
  5. 协议解析与路由
    • 解析帧头:从数据帧中提取出 IP 协议版本(IPv4 或 IPv6),并去掉链路层的头尾信息,就像拆开包裹查看里面是什么。
    • 解析 IP 头:根据 IP 头的信息,判断上层协议是 TCP 还是 UDP,为后续处理做准备。
  6. 数据分发到 Socket
    • 五元组匹配:根据源 IP、目标 IP、源端口、目标端口和协议类型(TCP/UDP),找到对应的 Socket,就像根据地址找到对应的房间。
    • 数据复制:将数据部分提取出来,放入对应 Socket 的接收缓存区,等待应用程序来取,就像将包裹放到你的门前。
    • 结束软中断:完成处理后,重新开启硬件中断,准备接收下一个包裹。
  7. 应用程序处理
    • 系统调用:你的应用程序(比如浏览器)通过系统调用(如 recv())从 Socket 的接收缓存区中取出数据,完成接收过程,就像你打开包裹,查看里面的内容。

2.2 详细步骤说明

2.2.1 网卡接收数据包

当网络设备(如网卡)通过物理媒介(如以太网、Wi-Fi)接收到数据包时,会利用 DMA 将数据包直接写入内存中的环形缓冲区(ring buffer)。环形缓冲区是一种高效的数据结构,允许网卡在固定大小的缓冲区内循环写入和读取数据包,减少内存管理开销。

2.2.2 触发硬件中断

数据包写入环形缓冲区后,网卡会向 CPU 发起硬件中断请求(IRQ)。硬件中断用于通知 CPU 有新的数据包到达,迫使 CPU 中断当前的任务,转而处理网络数据。

2.2.3 处理硬件中断
  1. 中断处理函数调用:
    • CPU 接收到中断请求后,会根据中断向量表查找对应的中断处理函数,并调用该函数。
  2. 屏蔽进一步中断:
    • 为了防止中断风暴(Interrupt Storm),中断处理函数会临时屏蔽同一中断源的进一步中断请求。
  3. 发起软中断:
    • 将数据处理任务交由软中断处理,以释放 CPU 及时响应其他硬件中断。
    • 软中断机制能够批量处理数据包,减少上下文切换次数,提高系统整体性能。
2.2.4 软中断处理

内核中的 ksoftirqd 线程负责处理软中断。在软中断处理过程中,ksoftirqd 会从环形缓冲区中逐个取出数据帧,并将其转换为 sk_buff 结构。sk_buff 是 Linux 内核中用于管理网络数据包的核心数据结构,包含了数据包的各种元数据和指针。

2.2.5 协议解析与路由
  1. 解析帧头:
    • 从数据帧中提取 IP 协议版本(IPv4 或 IPv6),并移除链路层的帧头和帧尾,获取 IP 层的数据。
  2. 解析 IP 头:
    • 根据 IP 头部的协议字段,判断上层协议是 TCP 还是 UDP,为后续的传输层处理做准备。
2.2.6 数据分发到 Socket
  1. 五元组匹配:
    • 根据源 IP、目标 IP、源端口、目标端口和协议类型(TCP/UDP),在内核的 Socket 表中查找对应的 Socket。
  2. 数据复制:
    • 将数据区部分提取出来,并放入找到的 Socket 的接收缓存区(Receive Buffer),等待应用程序读取。
  3. 结束软中断:
    • 完成数据包处理后,重新开启硬件中断,以便处理新的数据包到达。
2.2.7 应用程序处理

应用程序通过系统调用(如 recv()read() 等)从 Socket 的接收缓存区中读取数据,将其拷贝到应用层的缓冲区,完成数据接收过程。

3. 发送网络数据包的流程(TCP)

发送数据包的过程有点像你通过邮局寄送包裹,从打包到快递员取件,再到最终送达。以 TCP 为例,具体步骤如下:

3.1 数据包发送流程概述

  1. 应用程序发送数据:你在应用程序(如浏览器)中点击“发送”,用户数据会被拷贝到 sk_buff,并放入 Socket 的发送缓存区(UDP 通常没有发送缓存区,因为它不需要确认)。
  2. 协议栈准备数据:网络协议栈从 Socket 的发送缓存区取出 sk_buff,并克隆出一个新的 sk_buff,这是为了支持 TCP 的重传机制,确保数据不会因为丢失而无法恢复。
  3. 协议封装:数据在协议栈中逐层封装,添加 TCP 头部、IP 头部、MAC 头部和帧尾。TCP 会对数据进行分段,IP 可能会进行分片。
  4. 软中断通知网卡:一旦数据准备好,协议栈会通过软中断通知网卡驱动,有新的包裹(数据)需要发送。
  5. 网卡驱动发送数据:网卡驱动程序会从发送队列中依次取出 sk_buff,并写入环形缓冲区(ring buffer),这个区域是网卡通过 DMA 直接读取数据的地方。
  6. 触发网卡发送:网卡开始发送数据,发送成功后会触发硬件中断,通知系统发送完成,并释放 sk_buff 和环形缓冲区的内存(对于 TCP,释放的是克隆的 sk_buff,而 UDP 则释放原始的)。
  7. 处理 ACK 应答:对于 TCP,发送的数据需要等待对方的 ACK 确认。一旦收到 ACK,内核就会释放原始的 sk_buff,完成整个发送过程。

3.2 详细步骤说明

3.2.1 应用程序发送数据

当你在浏览器中点击“发送”按钮时,应用程序会通过系统调用(如 send()write())将用户的数据拷贝到一个 sk_buff 结构中,并放入对应 Socket 的发送缓存区。对于 UDP 来说,由于它不需要确认机制,所以通常不会有发送缓存区。

3.2.2 协议栈准备数据

网络协议栈会从 Socket 的发送缓存区中取出 sk_buff,并克隆出一个新的 sk_buff。这个克隆的 sk_buff 就像是为可能的重传做准备,以防数据在传输过程中丢失。

3.2.3 协议封装

数据在传输过程中会逐层添加协议头部,就像在寄送包裹时,每一层包装都加上必要的信息:

  1. 传输层(TCP)
    • 添加 TCP 头部信息,包括源端口、目标端口、序列号、确认号等。
    • 如果数据量大,TCP 会进行分段(Segmenting),确保每个数据段都能被正确传输。
  2. 网络层(IP)
    • 添加 IP 头部信息,包括源 IP 地址和目标 IP 地址。
    • 如果 IP 包过大,可能会进行分片(Fragmenting),将大包拆分成小片段传输。
  3. 数据链路层(MAC)
    • 添加链路层头部信息,包括源 MAC 地址和目标 MAC 地址。
    • 添加帧尾部(如 CRC 校验),确保数据在传输过程中没有被篡改。
3.2.4 软中断通知网卡

数据包封装完成后,协议栈会通过软中断机制通知网卡驱动程序,有新的数据包准备好要发送了。这就像是你在手机上点击“发送”按钮后,邮局系统自动安排快递员来取件。

3.2.5 网卡驱动发送数据

网卡驱动程序会从发送队列中依次取出 sk_buff,并将其写入环形缓冲区(ring buffer)。这个环形缓冲区位于内存的 DMA 区域,允许网卡通过 DMA 直接读取待发送的数据包,减少了 CPU 的负担,提高了传输效率。

3.2.6 触发网卡发送

一旦 sk_buff 被写入环形缓冲区,网卡就会开始实际的发送过程。发送成功后,网卡会触发一个硬件中断,通知系统数据已经成功发送:

  • 释放 sk_buff 和 ring buffer 内存
    • 对于 TCP,发送完成后释放克隆出的 sk_buff,保留原始的 sk_buff 等待 ACK 确认。
    • 对于 UDP,由于不需要确认机制,直接释放原始的 sk_buff
3.2.7 处理 ACK 应答

对于 TCP,发送的数据包需要等待对方的 ACK 确认。一旦收到 ACK,内核就会释放原始的 sk_buff,确保资源得到有效利用。如果没有收到 ACK,TCP 会根据超时机制重新发送数据包,确保数据的可靠传输。

4. sk_buff 结构

在 Linux 内核中,sk_buff(socket buffer)就像是网络数据包的“行李标签”,负责管理和传递网络数据。每个 sk_buff 包含以下信息:

  • 数据指针和长度:指向数据包的实际内容及其长度,就像包裹上的地址和内容描述。
  • 协议信息:标识数据包所属的协议层(如 IP、TCP),确保每一层都能正确处理数据。
  • 元数据:包含数据包的状态信息,比如接收和发送队列的位置、引用计数等,就像包裹的追踪信息。
  • 指针链sk_buff 可以通过链表形式连接,方便数据包的快速传输和处理,就像多个包裹通过运输带连接在一起。

sk_buff 使得内核能够高效地管理网络数据包的生命周期,从数据的接收、传输到释放,提供了统一的接口和管理机制。

5. 总结

整个 Linux 协议栈中的数据传输过程就像是一次精心安排的包裹运输,从应用层的“打包”开始,经过传输层、网络层、数据链路层,最终通过物理层的网卡发送或接收数据。每一层在数据封装或解封装的过程中都会添加或解析各自协议层的头部信息,确保数据能够顺利传输到目的地或从网络中正确接收。而 sk_buff 作为核心数据结构,就像是网络数据包的“行李标签”,在整个传输过程中扮演了关键角色,提供了高效的数据包管理机制。

参考:

0voice · GitHub

 

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

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

相关文章

JVM 虚拟机的编译器、类加载过程、类加载器有哪些?

JVM 虚拟机的编译器 编译器可以分为:前端编译器、JIT 编译器、AOT编译器。 前端编译器:源代码 --> 字节码 在Java语言中,JDK安装目录中的javac就是编译器。它负责将Java源代码编译为字节码。因为处于编译的前期,javac也叫做前…

C语言 | Leetcode C语言题解之第417题太平洋大西洋水流问题

题目: 题解: static const int dirs[4][2] {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};void bfs(int row, int col, bool ** ocean, const int ** heights, int m, int n) {if (ocean[row][col]) {return;}ocean[row][col] true;int * queue (int *)malloc…

如何安装和注册 GitLab Runner

如何安装和注册 GitLab Runner GitLab Runner 是一个用于运行 GitLab CI/CD (Continuous Integration/Continuous Deployment) 作业。它是一个与 GitLab 配合使用的应用程序,可以在本地或云中运行。Runner 可以执行不同类型的作业,例如编译代码、运行测…

有效安全计划评估的基本指标

衡量安全计划成功与否的最有效指标是什么? 最直接的指标是:您的组织是否遭到入侵?如果答案是肯定的,那么显然还有工作要做。如果答案是否定的,那么您的状况就更好了——但情况比这更复杂。 即使您没有遭到入侵&#…

视频理解大模型最新进展

文章目录 Video-LLaMAVision-Language BranchAudio-Language Branch Video-ChatGPTMiniGPT4-videoCogVLM2-Video(1)Pre-training(2)Post-training Qwen2-VLMA-LMMChat-UniVi大模型对比 Video-LLaMA 2023:阿里达摩院的…

JAVA虚拟机----JVM

(一)认识JVM JVM 是 Java Virtual Machine 的简称,意为 Java虚拟机。 虚拟机是指通过软件模拟的具有完整硬件功能的、运⾏在⼀个完全隔离的环境中的完整计算机系统。 常⻅的虚拟机:JVM、VMwave、Virtual Box。 (二)JVM运…

2017年国赛高教杯数学建模C题颜色与物质浓度辨识解题全过程文档及程序

2017年国赛高教杯数学建模 C题 颜色与物质浓度辨识 比色法是目前常用的一种检测物质浓度的方法,即把待测物质制备成溶液后滴在特定的白色试纸表面,等其充分反应以后获得一张有颜色的试纸,再把该颜色试纸与一个标准比色卡进行对比&#xff0c…

如何查看电脑什么时候被人动过及看过的文件?

一、查看Windows事件查看器 Windows系统具有强大的日志记录功能,通过“事件查看器”可以查看电脑的使用记录。具体步骤如下: 按下Win R组合键打开运行窗口,输入eventvwr.msc命令并回车,打开事件查看器。 在事件查看器中&#x…

solidwork镜像实体

效果如下: 可以看到这两条线是对称的。 第一步,点击这条要镜像的边,接着点击镜像实体。 然后选择镜像轴,即可

OpenHarmony标准系统mipi摄像头适配

OpenHarmony标准系统mipi摄像头适配 本文档以rk3568为例,讲述如何在OpenHarmony 标准系统rk设备上适配mipi摄像头。 开发环境 OpenHarmony标准系统4.1rrk3568设备摄像头ov5648,ov8858 文档约定:4.1r_3568为OpenHarmony标准系统源码根目录 1.适配准备:得…

苹果CMS插件:优化蜘蛛访问内容,提升百度收录率

确保蜘蛛抓取原始内容 专为苹果CMS设计的广告管理插件,能够智能识别搜索引擎蜘蛛与普通访客,确保蜘蛛访问时展示原始内容,从而提升被百度等搜索引擎收录的几率。 广告显示提升收益 对于普通访客,该插件则优先显示广告内容&#…

UnLua扩展C++函数和蓝图自定义事件

一、通过BlueprintImplementableEvent标记扩展C函数 1、 这个标记表示C不需要实现,让蓝图/Lua重写。 2、首先在C中将LuaImp函数标记为BlueprintImplementableEvent,不需要实现,然后再GetIndex中调用该函数。 MyBaseActor.h UFUNCTION(Bluepr…

电力电塔电线缺陷检测数据集 voc yolo

电力 电塔电线缺陷检测数据集 10000张 带标注 voc yolo 电力电塔电线缺陷检测数据集 数据集描述 该数据集旨在用于电力电塔和电线的缺陷检测任务,涵盖多种常见的缺陷类型。数据集包含了大量的图像及其对应的标注信息,可用于训练计算机视觉模型&#x…

DEPLOT: One-shot visual language reasoning by plot-to-table translation论文阅读

文章链接:https://arxiv.org/abs/2308.01979http://arxiv.org/abs/2212.10505https://arxiv.org/abs/2308.01979 源码链接:https://github.com/cse-ai-lab/RealCQA Abstract 理解图表需要很强的推理能力,之前的最先进 (SOTA&…

圆周阵列元件的间距增加操作方法

在进行器件圆周阵列时,内圈的角度和外圈的旋转角度都相同,由于内圈的圆周长小于外圈的圆周长,有可能在内圈造成部分元件之间有两个焊盘会有覆盖的情况,此时需要对内圈的元件位置进行微调,需要增加在同一半径位置的元件…

数据结构 ——— 算法的时间复杂度

目录 时间复杂度的概念 时间复杂度函数式 大O的渐进表示法的概念 大O的渐进表示法 时间复杂度的概念 在计算机科学中,算法的时间复杂度是一个函数(数学上的函数式),它定量描述了该算法的运行时间,一个算法执行所耗…

Netty笔记10-Netty参数调优

文章目录 一、CONNECT_TIMEOUT_MILLISCONNECT_TIMEOUT_MILLIS设置为1秒超时CONNECT_TIMEOUT_MILLIS设置为5秒超时注意事项 二、SO_BACKLOG代码示例注意事项 三、ulimit -n(文件描述符)设置文件描述符限制在注意事项 四、TCP_NODELAY使用 TCP_NODELAY 的场景注意事项 五、SO_SND…

软件安全最佳实践:首先关注的地方

尽管组织拥有大量可用的工具,但应用程序安全性仍然不足。 最近的数据显示,在过去四到五年中,软件供应链攻击同比增长了 600-700%,超过一半的美国企业在过去 12 个月中遭受过某种形式的软件供应链攻击。 为何应用程序安全工作未…

签署《AI安全国际对话威尼斯共识》 智源持续推动人工智能安全发展

近日,由AI安全国际论坛(Safe AI Forum)和博古睿研究院(Berggruen Institute) 共同举办的第三届国际AI安全对话(International Dialogues on AI Safety)在威尼斯举办。图灵奖得主Yoshua Bengio、姚期智教授&…

电气设备施工现场风险状态判断ai模型训练数据集

电气设备施工现场风险状态判断ai模型训练数据集 id:18 电气设备施工现场工人人工智能学习数据和工作环境安全数据,建立系统化管理体系,改变全球EHS范式,预防工业事故。数据集记录了387709例子电力设施建设以及施工现场相关的灾害安全环境数据…