小林coding图解计算机网络|基础篇03|Linux 系统是如何收发网络包的?

小林coding网站通道:入口
本篇文章摘抄应付面试的重点内容,详细内容还请移步:小林coding网站通道

文章目录

  • 网络模型
  • Linux 网络协议栈
  • Linux 接收网络包的流程
  • Linux发送网络包的流程
    • 为什么全部数据包只用一个结构体来描述呢
    • 发送网络数据的时候,涉及几次内存拷贝操作?

网络模型

由于 OSI 模型实在太复杂,提出的也只是概念理论上的分层,并没有提供具体的实现方案。

事实上,我们比较常见,也比较实用的是四层模型,即 TCP/IP 网络模型,Linux 系统正是按照这套网络模型来实现网络协议栈的。

Linux 网络协议栈

首先我们需要了解TCP/IP网络模型,以及网络包的封装原理。
Linux网络协议栈就类似于TCP/IP的四层结构。

从图中的网络一些栈,可以看到: + 应用程序需要通过系统调用,来跟Socket层进行数据交换 + Socket层的下面就是传输层、网络层和网络接口层 + 最下面的一层,则是网卡驱动程序和硬件网卡设备

LVS是什么?
LVS(Linux Virtual Server)是Linux系统中用于实现负载均衡的高性能和高可用性服务。它主要用于构建可扩展、高可用的网络服务,如Web、邮件、媒体流等。通过LVS,可以将网络请求分发到由多个服务器组成的服务器集群中,这样不仅可以提高服务的处理能力,还可以提高服务的可用性和可靠性。

LVS工作在网络的传输层,它使用IP层的负载均衡技术,支持多种负载均衡算法,包括轮询(Round Robin)、加权轮询(Weighted Round Robin)、最少连接(Least Connections)、加权最少连接(Weighted Least Connections)等。这些算法可以根据实际需求灵活选择,以达到最优的负载均衡效果。

LVS的负载均衡机制主要有三种模式:

  1. NAT(Network Address Translation)模式:在这种模式下,请求会被转发到内部服务器,而内部服务器的响应则被发送回LVS服务器,然后再由LVS服务器发送给客户端。这种方式简单易于部署,但可能会因为所有的响应数据都需要经过LVS服务器而成为瓶颈。

  2. 直接路由(Direct Routing)模式:客户端的请求直接路由到后端服务器,而响应则直接从后端服务器返回给客户端,绕过了LVS服务器。这种模式能够减少LVS服务器的负载,提高系统的处理能力,但需要在网络配置上做一些额外的工作。

  3. 隧道模式(TUN/IP Tunneling):在这种模式下,请求被封装在IP隧道中并直接发送到最终的服务器。这种方式适用于跨越不同网络的负载均衡,但可能需要在服务器上进行额外的配置。


Socket是什么?
Socket是一种抽象层,它为在不同主机间进行数据交换提供了一组编程接口(API)。它是网络通信的基石,提供了构建多种网络应用的基础,包括Web服务器、电子邮件客户端、聊天程序等。Socket使得程序可以读写数据,就像对本地文件进行操作一样简单。

Socket为网络通信提供了一个统一的编程接口,简化了网络程序的开发。通过使用Socket,开发者可以不必深入了解底层网络协议的细节,就能构建复杂的网络应用。此外,Socket编程接口在不同的操作系统中都有实现,使得基于Socket的应用可以跨平台运行,进一步提高了网络程序的可移植性和灵活性。

Linux 接收网络包的流程

网卡是计算机里的一个硬件,专门负责接收和发送网络包,当网卡接收到一个网络包后,会通过 DMA 技术,将网络包写入到指定的内存地址,也就是写入到 Ring Buffer ,这个是一个环形缓冲区,接着就会告诉操作系统这个网络包已经到达。

DMA技术

DMA(Direct Memory Access)技术是一种允许某些硬件子系统直接读写主内存(RAM),而无需中央处理单元(CPU)介入的计算机系统特性。这种方式可以大大减少CPU的负担和提高整个系统的数据处理效率。

那应该怎么告诉操作系统这个网络包已经到达了呢?

最简单的一种方式就是触发中断,也就是每当网卡收到一个网络包,就触发一个中断告诉操作系统。

但是,在高性能网络场景下,网络包的数量会非常多,那么就会触发非常多的中断那么频繁地触发中断,则会导致 CPU 一直没完没了的处理中断,而导致其他任务可能无法继续前进,从而影响系统的整体效率。

所以为了解决频繁中断带来的性能开销,Linux 内核在 2.6 版本中引入了 NAPI 机制,它是混合「中断和轮询」的方式来接收网络包,它的核心概念就是不采用中断的方式读取数据,而是首先采用中断唤醒数据接收的服务程序,然后 poll 的方法来轮询数据。

因此,当有网络包到达时,会通过 DMA 技术,将网络包写入到指定的内存地址,接着网卡向 CPU 发起硬件中断,当 CPU 收到硬件中断请求后,根据中断表,调用已经注册的中断处理函数。

硬件中断处理函数会做如下的事情:

  • 需要先「暂时屏蔽中断」,表示已经知道内存中有数据了,告诉网卡下次再收到数据包直接写内存就可以了,不要再通知 CPU 了,这样可以提高效率,避免 CPU 不停的被中断。
  • 接着,发起「软中断」,然后恢复刚才屏蔽的中断。

至此,硬件中断处理函数的工作就已经完成。

软中断的处理

内核中的 ksoftirqd 线程专门负责软中断的处理,当 ksoftirqd 内核线程收到软中断后,就会来轮询处理数据。

ksoftirqd 线程会从 Ring Buffer 中获取一个数据帧,用 sk_buff 表示,从而可以作为一个网络包交给网络协议栈进行逐层处理。

网络协议栈作用

  • 先进入到网络接口层,在这一层会检查报文的合法性,如果不合法则丢弃,合法则会找出该网络包的上层协议的类型,比如是 IPv4,还是 IPv6,接着再去掉帧头和帧尾,然后交给网络层。

  • 到了网络层,则取出 IP 包,判断网络包下一步的走向,比如是交给上层处理还是转发出去。当确认这个网络包要发送给本机后,就会从 IP 头里看看上一层协议的类型是 TCP 还是 UDP,接着去掉 IP 头,然后交给传输层。

  • 传输层取出 TCP 头或 UDP 头根据四元组「源 IP、源端口、目的 IP、目的端口」 作为标识找出对应的 Socket,并把数据放到 Socket 的接收缓冲区

  • 最后,应用层程序调用 Socket 接口,将内核的 Socket 接收缓冲区的数据「拷贝」到应用层的缓冲区,然后唤醒用户进程。

至此,一个网络包的接收过程就已经结束了,你也可以从下图左边部分看到网络包接收的流程,右边部分刚好反过来,它是网络包发送的流程。

Linux发送网络包的流程

发送网络包的流程正好和接收流程相反。如上图中的右半部分。

  • 首先,应用程序会调用 Socket 发送数据包的接口,由于这个是系统调用,所以会从用户态陷入到内核态中的 Socket 层,内核会申请一个内核态的 sk_buff 内存,将用户待发送的数据拷贝到 sk_buff 内存,并将其加入到发送缓冲区

  • 接下来,网络协议栈从 Socket 发送缓冲区中取出 sk_buff,并按照 TCP/IP 协议栈从上到下逐层处理

  • 如果使用的是 TCP 传输协议发送数据,那么先拷贝一个新的 sk_buff 副本 (这是因为 sk_buff 后续在调用网络层,最后到达网卡发送完成的时候,这个 sk_buff 会被释放掉)。而 TCP 协议是支持丢失重传的,在收到对方的 ACK 之前,这个 sk_buff 不能被删除。所以内核的做法就是每次调用网卡发送的时候,实际上传递出去的是 sk_buff 的一个拷贝,等收到 ACK 再真正删除

  • 接着,对 sk_buff 填充 TCP 头。这里提一下,sk_buff 可以表示各个层的数据包,在应用层数据包叫 data,在 TCP 层我们称为 segment,在 IP 层我们叫 packet,在数据链路层称为 frame
    至此,传输层的工作也就都完成了。

  • 交给网络层,在网络层里会做这些工作:选取路由(确认下一跳的 IP)填充 IP 头netfilter 过滤对超过 MTU 大小的数据包进行分片。处理完这些工作后会交给网络接口层处理。

  • 网络接口层会通过 ARP 协议获得下一跳的 MAC 地址,然后对 sk_buff 填充帧头和帧尾,接着将 sk_buff 放到网卡的发送队列中。

  • 这一些工作准备好后,会触发**「软中断」告诉网卡驱动程序,这里有新的网络包需要发送,驱动程序会从发送队列中读取 sk_buff**,将这个 sk_buff 挂到 RingBuffer 中,接着将 sk_buff 数据映射到网卡可访问的内存 DMA 区域,最后触发真实的发送。

  • 当数据发送完成以后,其实工作并没有结束,因为内存还没有清理。当发送完成的时候,网卡设备会触发一个硬中断来释放内存,主要是释放 sk_buff 内存和清理 RingBuffer 内存

  • 最后,当收到这个 TCP 报文的 ACK 应答时,传输层就会释放原始的 sk_buff

为什么全部数据包只用一个结构体来描述呢

协议栈采用的是分层结构,上层向下层传递数据时需要增加包头,下层向上层数据时又需要去掉包头,如果每一层都用一个结构体,那在层之间传递数据的时候,就要发生多次拷贝,这将大大降低 CPU 效率。

于是,为了在层级之间传递数据时,不发生拷贝,只用 sk_buff 一个结构体来描述所有的网络包,那它是如何做到的呢?是通过调整 sk_buff 中 data 的指针,比如:

  • 接收报文时,从网卡驱动开始,通过协议栈层层往上传送数据报,通过增加 skb->data 的值,来逐步剥离协议首部。
  • 要发送报文时,创建 sk_buff 结构体,数据缓存区的头部预留足够的空间,用来填充各层首部,在经过各下层协议时,通过减少 skb->data 的值来增加协议首部。

你可以从下面这张图看到,当发送报文时,data 指针的移动过程。

发送网络数据的时候,涉及几次内存拷贝操作?

  • 第一次,调用发送数据的系统调用的时候,内核会申请一个内核态的 sk_buff 内存,将用户待发送的数据拷贝到 sk_buff 内存,并将其加入到发送缓冲区。

  • 第二次,在使用 TCP 传输协议的情况下,从传输层进入网络层的时候,每一个 sk_buff 都会被克隆一个新的副本出来。副本 sk_buff 会被送往网络层,等它发送完的时候就会释放掉,然后原始的 sk_buff 还保留在传输层,目的是为了实现 TCP 的可靠传输,等收到这个数据包的 ACK 时,才会释放原始的 sk_buff 。

  • 第三次,当 IP 层发现 sk_buff 大于 MTU 时才需要进行。会再申请额外的 sk_buff,并将原来的 sk_buff 拷贝为多个小的 sk_buff

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[HackMyVM]靶场Logan2

难度:Medium kali:192.168.56.104 靶机:192.168.56.146 端口扫描 ┌──(root㉿kali2)-[~/Desktop] └─# nmap 192.168.56.146 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-04-04 19:41 CST Nmap scan report for 192.168.56.146 Host is up (0.000067s latency)…

0201基础集成与使用-微信支付-支付模块-项目实战

文章目录 一、前言二、springboot集成2.1 配置信息与配置类2.2 微信相关枚举信息2.3 工具类2.4 业务接口 三、演示-支付与退款结语 一、前言 下面我以微信支付v3为例,通过spirngboot集成到我们的项目中,不依赖其他第三方框架。当然适用简单项目&#xf…

软考--软件设计师(软件工程总结2)

目录 1.测试方法 2.软件项目管理 3.软件容错技术 4.软件复杂性度量 5.结构化分析方法(一种面向数据流的开发方法) 6.数据流图 1.测试方法 软件测试:静态测试(被测程序采用人工检测,计算机辅助静态分析的手段&…

Unity开发之音效相关

目录 音频文件的导入 音频源相关 麦克风输入相关 获取麦克风设备信息 开始录制 获取音频数据用于存储或者传输 代码控制音频源 动态控制音效播放 示例 音频文件的导入 常用格式:wav,mp3,ogg,aiff Force To Mono(多声道转单声道)Normalize(强制为单声道&am…

C++入门 (2) >>引用>>内联函数>>auto关键字

1 引用 定义:给变量起别名。 方法:在类型后面加上&符号。 主要作用:代替函数传指针。 例: void test(int& a) //参数为int&类型 {a 10; }int main() {int m 3;int& z m; //给m起别名叫z&#xff0…

基于springboot+vue+Mysql的在线考试系统

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…

MySQL8,体验不一样的安装方式!

MySQL官网中下载YUM源rpm安装包。 1、把上面的rpm文件下载下来放到服务器上 #或者在linux系统中通过wget命令下载 wget http://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm2、下载完成后使用yum命令本地安装yum源 yum localinstall mysql80-community-rel…

Linux云计算之Linux基础3——Linux基本认识操作

1、终端 终端(terminal):人和系统交互的必要设备,人机交互最后一个界面(包含独立的输入输出设备) 物理终端(console):直接接入本机器的键盘设备和显示器虚拟终端(tty):通过软件方式虚拟实现的终端。它可以…

IP-guard WebServer 任意文件读取漏洞复现

0x01 产品简介 IP-guard是由溢信科技股份有限公司开发的一款终端安全管理软件,旨在帮助企业保护终端设备安全、数据安全、管理网络使用和简化IT系统管理。 0x02 漏洞概述 由于IP-guard WebServer /ipg/static/appr/lib/flexpaper/php/view.php接口处未对用户输入的数据进行严…

VMamba: Visual State Space Model

VMamba: Visual State Space Model VMamba:视觉状态空间模型 论文链接:http://arxiv.org/abs/2401.10166 代码链接:https://github.com/MzeroMiko/VMamba 1、摘要 借鉴了最近引入的状态空间模型SSM,提出了Visual State Space M…

如何保证Redis的缓存和数据库中的数据的一致性?

Redis的缓存如何和数据库中的数据保持一致性? 我们都知道,Redis是一个基于内存的键值存储系统,数据完全存放在内存中,这使得它的读写速度远超传统的硬盘存储数据库。对于高访问频率、低修改率的数据,通过将它们缓存在…

动态规划:线性dp

1.最长公共子序列(LCS) dp[i][j]含义:序列Ai(a1-ai)和Bj(b1-bj)的最长公共子序列长度 分析两种情况: (1)当ai bj时,已经求得Ai-1和Bj-1的最长公共子序列 dp[i][j] dp[i-1][j-1] 1 (2)当…

C++:比较运算符(18)

就是进行数据的比较&#xff0c;表达式正确的话就是真&#xff0c;错的话就是假&#xff0c;真假则由bool值来代替&#xff0c;非0即真 等于&#xff08;为赋值&#xff0c;为比较&#xff09;10 200!不等于10 ! 201>大于10 > 200<小于10 < 201>大于等于20 >…

windows安装Openssl

openssl官网:[ Downloads ] - /source/index.html Windows 安装方法 OpenSSL 官网没有提供 Windows 版本的安装包&#xff0c;可以选择其他开源平台提供的工具 Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions 等待下载完成 捐不起 配置环境变量 ope…

【图论】【基环内向树】【广度优先】【深度优先】2127. 参加会议的最多员工数

作者推荐 视频算法专题 本文涉及知识点 图论 基环内向树 LeetCode2127. 参加会议的最多员工数 一个公司准备组织一场会议&#xff0c;邀请名单上有 n 位员工。公司准备了一张 圆形 的桌子&#xff0c;可以坐下 任意数目 的员工。 员工编号为 0 到 n - 1 。每位员工都有一位…

XML --java学习笔记

XML(全称EXtensible Markup Language&#xff0c;可扩展标记语言) 本质是一种数据的格式&#xff0c;可以用来存储复杂的数据结构&#xff0c;和数据关系 XML的特点 XML中的“<标签名>”称为一个标签或一个元素&#xff0c;一般是成对出现的XML中的标签名可以自己定义…

数字信号处理实验---FFT分析

一、题目&#xff1a; 二、实验要求&#xff1a; 1、绘制图形时&#xff0c;尽量选用已经提供的函数。 2、所有的图形&#xff0c;需要加上横坐标、纵坐标以及标题的说明。 3、将设计的程序保存为脚本文件&#xff0c;在实验报告中&#xff0c;需写出程序语句。 4、Matlab程…

【GlobalMapper精品教程】073:像素到点(Pixels-to-Points)从无人机图像轻松生成点云

文章目录 一、工具介绍二、生成点云三、生成正射四、生成3D模型五、注意事项一、工具介绍 Global Mapper v19引入的新的像素到点工具使用摄影测量原理,从重叠图像生成高密度点云、正射影像及三维模型。它使LiDAR模块成为已经功能很强大的的必备Global Mapper扩展功能。 打开…

安装geopandas很简单。。。

创建新环境 创建新环境并不是绝对必要的&#xff0c;但考虑到安装来自不同通道的其他地理空间包可能会导致依赖冲突 &#xff0c;安装新环境可能是很好的做法&#xff0c;在干净的环境中堆叠&#xff0c;重新开始。 以下命令创建一个名为geo_env的新环境&#xff0c; 将其配置…

CANoe之使用以及车载项目实操总结

以下是我通过8年的项目实操自我总结的一些经验和技术&#xff0c;作为一名奋斗在一线的研发人员&#xff0c;无时无刻不在做自我总结&#xff0c;所有的总结都是通过日报、周报、月报提炼出来的&#xff0c;实践是检验技术的唯一标准&#xff1b; 欢迎大家的交流和分享 思维导…