《深入理解Linux网络》笔记

《深入理解Linux网络》笔记

  • 前言
  • 参考

前言

前段时间看了《深入理解Linux网络》这本书,虽然有些地方有以代码充篇幅的嫌疑,但总体来说还是值得一看的。在这里简单记录一下笔记,记录下对网络新的理解。


  • 内核是如果接受网络包的?
    在这里插入图片描述
    如上图所示,整个流程基本如下:
  • 数据包首先从网络中到达主机中的网卡设备
  • 网卡通过DMA把数据帧运到内存中
  • 之后网卡通过触发硬终端(触发电平变化)来通知CPU有网络包到达
  • CPU收到硬中断之后,会调用网络设备注册的中断处理函数。在这个函数中响应中断进行简单的处理,燃弧发出软中断(linux中整个中断过程分为上半部(硬中断)和下半部(软中断))。
  • 内核线程(ksoftirqd线程, 内核启动的时候会专门创建一些软中断内核线程,一般来说,机器上有几个核心就会有几个ksoftirqd内核线程)响应软中断,调用网卡驱动注册的poll函数开始收包。从RingBuffer中(就是之前DMA运输的地方)摘取一个帧,然后交给上层的协议栈进行具体的处理。
  • tcpdump抓包和iptable过滤包的原理大概是什么?
    tcpdump是一个常用的抓包工具,其原理概括来说就是通过类似一个回调的机制,将其挂到网络包传输的路径中。当有网络包到来(或者发送出去)的时候内核会调用将数据包传给tcpdump的回调函数,就可以达到抓包的效果。

    iptable其实本质上也一样,只不过iptable会对经过的包进行过滤、修改。而tcpdump一般只是查看。
    有一点不一样的是,tcpdump是工作在设备层的(所以tcpdump还可以查看数据链路层的一些包信息),而iptable是工作在IP层(ARP层)的。
    如下图所示。
    在这里插入图片描述
    在这里插入图片描述
    ps: netfilter可以理解就是 iptable。
  • top命令中hi,si代表啥意思?
    在这里插入图片描述
    如果了解了linux的中断原理,也就对top命令中hi,si有了更深的理解。hi代表硬中断的开销,si代表软中断的开销
  • 关于系统调用陷入内核态的一些理解
    对于一个程序来说,通过系统调用(比如说write数据到网络中)陷入内核态之后,还依旧执行的是这个程序的活系统还依旧算着这个进程的cpu运行时间),只不过是陷入到了内核态,算是这个程序的内核态线程(并不是新建了一个内核态线程)在执行。这也就是所谓的进程的内核上下文。
  • 如果使用的是普通的同步阻塞网络读写调用,一般来说,会进行至少两次进程的上下文切换(一个是无数据到达时阻塞、另一个是数据到达时唤醒)。一般来说,每一次进程的上下文切换都需要花费3-5微秒的时间,以CPU视角来说,这其实已经不少了,而且上下文的切换并没有干什么实质性的活,所以,很多机制都尽量减少不必要的上下文切换(比如说自旋锁、 epoll等机制。)
  • epoll、poll等多路复用机制高效在什么地方?
    在我看来,多路复用机制高效的本质在于可以同时监听多个套接字,这样就一旦其中有需要读写的事件到来,就可以尽量减少进程的上下文切换(不像同步操作read、write那样进行频繁的阻塞),让进程更专注的处理网络请求。

    整个epoll机制基本如下图所示。
    在这里插入图片描述
    通过epoll_ctl加入需要监听的多个套接字。当某一个套接字对应的网络包从网卡到来之时,通过内核的软硬件中断进行处理,然后将请求放入epoll对象的就绪列表中。

    epoll_wait就是从就绪列表中看是否有事件到达,如果有则取出进行处理。 在高并发的场景中,epoll_wait会一直处理,知道没活的时候才会让出CPU.

    而红黑树只是epoll中用来快速查找、删除socket时用的数据结构,并不是epoll支持高并发的根本原因。
  • 关于tcp分段和ip分片的一些理解
    对于一般的tcp传输来说,下层的mac协议限制的帧的大小,MTU一般是1500字节。如果超过了MTU,mac层将无法传输(应该会丢弃)。对应MTU,ip层也有响应的长度限制MSS,如果超过了这个限制之后,ip层会执行分片,以避免mac层将数据丢弃。但是ip层的分片会导致一些问题:一个是额外的分片开销;另一个是如果一个分片丢失了,上层的整个包都需要重传(对于TCP来说整个包会重传,对于UDP来说,数据包就是丢失了);

    所以,tcp层为了减少ip分片,在tcp层就将数据包进行了分段,使装入ip层数据不大于MSS,这样,ip层就不会进行分片,也不会有一个分片丢失,整个数据包都得重传的尴尬。
  • 如果想通过网络发送一个文件,会涉及到哪些内存拷贝呢?
    一般来说,我们想通过网络发送一个本地的文件,会首先通过read()系统调用将文件读到内存中,然后在write()到远端。这其中涉及到磁盘-内核空间-用户空间的内存拷贝过程
    如下图所示。一共涉及到4次的用户态和内核态的上下文切换和4次的内存拷贝。
    在这里插入图片描述
    仔细分析一下其实知道,如果不需要再用户空间修改文件内容的话,完全不需要将数据拷贝到用户空间。
    所以,一般来说有几种方式可以提高这种场景的内存效率。
    1. 通过 mmap + write
      即通过linux提供的mmap内存映射,将内核缓冲区里的数据映射到用户空间,这样,操作系统内核与用户空间就不需要再进行任何的数据拷贝操作。
      在这里插入图片描述这样需要4次的用户态和内核态的上下文切换,和3次的内存拷贝。
    2. 使用sendfile系统调用
      在 Linux 内核版本 2.1 中,提供了一个专门发送文件的系统调用函数 sendfile()。该系统调用,可以直接把内核缓冲区里的数据拷贝到 socket 缓冲区里,不再拷贝到用户态,这样就只有 2 次上下文切换,和 3 次数据拷贝。
      sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
      在这里插入图片描述
      而且从 Linux 内核 2.4 版本开始起, 对于支持 SG-DMA 技术的网卡,sendfile还可以进一步减少cpu的干预,直接从内存缓存中拷贝到网卡,如下图所示。
      在这里插入图片描述算是真正做到了零拷贝。
      kafka之所以性能突出,一个重要的原因就是利用了这种零拷贝技术。
  • 关于linux路由表
    linux默认情况下会丢掉不属于本机IP的数据包。将net.ipv4.ip_forward设置为1后,会开启路由功能,Linux会像路由器一样对不属于本机的IP数据包进行路由转发。

    linux可以配置多个路由表,默认有三个已有的路由表:
    在这里插入图片描述> 1. local: 处理本地IP和广播地址路由,local路由表只由kernel维护,不能更改和删除
    2. main: 处理所有非策略路由,不指定路由表名时默认使用的路由表
    3. default: 所有其他路由表都没有匹配到的情况下,根据该表中的条目进行处理
  • 关于本机网络
    在这里插入图片描述
    我们使用ifconfig可以看到一个lo的回环设备,这是内核虚拟出来的一个本机网卡设备,所有127.0.0.1的网络IO都直接通过这个lo进行传输,不需要经过实际的网络设备,所以即使拔了网线,也依然可以对127.0.0.1的网络IO进行请求。

    除了127.0.0.1之外,本机ip(如上图中的10.0.20.6)也是一样的,使用本机ip也可以访问本地服务,走的也是lo回环设备。
  • listen系统调用本质上是在干啥?
    对于我们熟知的网络系统调用Listen来说,其一个重要的作用就是在内核中建立并初始化好半队列(用来存储经过第一次握手的socket)和全队列(用来存储已经建立连接的socket, accept 其实就是从这里消费tcp连接的)的数据接口,为接下来TCP的握手连接做好准备。
  • 关于tcp的建立过程的一些细节
    tcp通过三次握手来建立连接。 一般来说,
    1. 客户端通过connect来建立连接,客户端发送SYN 连接握手请求,然后启动定时器
    2. 服务端收到请求之后,内核会发出SYN ACK, 这个时候将请求放入半连接队列。 同时也会启动一个重传定时器(所以如第二次握手发出之后,迟迟收不到第三次握手, 服务端会进行重传第二次握手)。
    3. 然后客户端收到SYN ACK之后,清除重传定时器,将连接置为已连接,然后发送第三次握手ACK。
  1. 服务端收到第三次握手之后,将连接冲半连接队列里删除,然后加入全连接队列。等待accept来消费连接
    整个过程如下图所示。
    在这里插入图片描述
    一般来说,建立一个tcp连接需要1.5个RTT, 根据通信双方的远近一般需要几十到几百毫秒的样子。 (一般来说,同地区的不同机房一般大约是几ms,北京到广东大概30-40ms)
  • 一条空的tcpl连接(只建立连接但是不发送数据)大概需要3-4kb的内存空间。 一条TIME_WAIT状态的连接需要消耗0.4kb的样子。所以机器上如果TIME_WAIT过多一般影响的不是内存而是端口号。
  • 一个机器可以建立多少个连接?
    要理解,一条tcp连接是有(src ip, src port, dst ip, dsp port) 四元组来构成的,所以对于一个客户端来说,说是根据16bit 的port 只能建立65536个连接,这是不正确的。 限制服务器端和客户端连接的最主要的是内存和cpu,如果这些是充足的,一台服务器建立百万连接完全是可能的。

参考

【1】《深入理解Linux网络》
【2】为什么 TCP/IP 协议会拆分数据
【3】Linux 内存拷贝

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

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

相关文章

数仓-可累计,半累加,不可累加指标,是什么,举例说明及解决方案

目录 1. 可累计指标定义:举例:解决方案: 2. 半累加指标定义:举例:解决方案: 3. 不可累加指标定义:举例:解决方案: 4. 总结对比5. 实际场景中的注意事项 这是数据仓库设计…

NestJS 的核心构建块有哪些?请简要描述它们的作用(例如,Modules, Controllers, Providers)

NestJS 核心构建块解析(Modules、Controllers、Providers) NestJS 是一个基于 TypeScript 的渐进式 Node.js 框架,核心设计借鉴了 Angular 的模块化思想。下面从实际开发角度解析它的三大核心构建块,并附代码示例和避坑指南。 一…

vue2 上传pdf,拖拽盖章,下载图片

效果图片&#xff1a; 不多废话上代码&#xff1a; <template><div class"pdf-stamp" onbeforecopyreturn false onselectdocument.selection.empty() ondragstartreturn false onselectstart return false ><div class"scroll-box" scro…

理性地倾听与表达:检索算法的语言学改进

论文标题 Rational Retrieval Acts: Leveraging Pragmatic Reasoning to Improve Sparse Retrieval 论文地址 https://arxiv.org/pdf/2505.03676 代码地址 https://github.com/arthur-75/Rational-Retrieval-Acts 作者背景 巴黎萨克雷大学&#xff0c;索邦大学&#xff…

MySQL及线程关于锁的面试题

目录 1.了解过 MySQL 死锁问题吗&#xff1f; 2.什么是线程死锁&#xff1f;死锁相关面试题 2.1 什么是死锁&#xff1a; 2.2 形成死锁的四个必要条件是什么&#xff1f; 2.3 如何避免线程死锁&#xff1f; 3. MySQL 怎么排查死锁问题&#xff1f; 4.Java线上死锁问题如…

【Reality Capture 】Reality Capture1.5中文版安装教程(附安装包下载)

文章目录 一、Reality Capture1.5中文版安装教程二、拷贝中文补丁三、Reality Capture1.5中文版下载地址一、Reality Capture1.5中文版安装教程 1. Reality Capture v1.4.0汉化版安装包下载并解压 2. 运行EpicInstaller-15.17.1-4a91a118786f4c2aa3c0093b23f83863.msi 3. 更改…

SVG数据可视化设计(AI)完全工作流解读|计育韬

AI 的 SVG 创作极限在哪里&#xff1f;绝不是那些初级的流程图生成和粗糙的商业模型设计。以下是由我们 JZ Creative Studio 通过 Claude 和 Deepseek 开展的专业级 SVG Data Visualization 创作&#xff0c;应广大读者强烈要求&#xff0c;专程直播讲授了一期 AI 工作流分享。…

not a genuine st device abort connection的问题

1.魔法棒里面电机Settings 2.然后在Other里面把Enabled的钩子去掉

uv简单使用

通过uv创建项目和虚拟环境 初始化项目 uv init --package my-project 初始化一个名为 my-project 的新项目&#xff0c;并生成必要的文件结构。 创建虚拟环境 uv venv .venv 激活虚拟环境 # For Windows .venv\Scripts\activate# For macOS/Linux source .venv/bin/acti…

测试左移系列-产品经理实战-实战认知1

课程&#xff1a;B站大学 记录产品经理实战项目系统性学习&#xff0c;从产品思维&#xff0c;用户画像&#xff0c;用户体验&#xff0c;增长数据驱动等不同方向理解产品&#xff0c;从0到1去理解产品从需求到落地的全过程&#xff0c;测试左移方向&#xff08;靠近需求、设计…

从需求到用例的AI路径:准确率与挑战

用工作流生成测试用例和自动化测试脚本&#xff01; 引言&#xff1a;用例的黄金起点 在软件工程中&#xff0c;“测试用例”是连接需求理解与质量保障之间的关键桥梁。一份高质量的测试用例&#xff0c;不仅是验证功能实现是否符合需求的工具&#xff0c;更是产品风险感知、用…

大语言模型中的“温度”参数到底是什么?如何正确设置?

近年来&#xff0c;市面上涌现了大量调用大模型的工具&#xff0c;如 Dify、Cherry Studio 等开源或自研平台&#xff0c;几乎都提供了 “温度”&#xff08;Temperature&#xff09; 选项。然而&#xff0c;很多人在使用时并不清楚该如何选择合适的温度值。 今天&#xff0c;…

如何删除网上下载的资源后面的文字

这是我在爱给网上下载的音效资源&#xff0c;但是发现资源后面跟了一大段无关紧要的文本&#xff0c;但是修改资源名称后还是有。解决办法是打开属性然后删掉资源的标签即可。

hot100-子串-JS

一、560.和为k的子串 560. 和为 K 的子数组 提示 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2示例 2…

01背包类问题

文章目录 [模版]01背包1. 第一问: 背包不一定能装满(1) 状态表示(2) 状态转移方程(3) 初始化(4) 填表顺序(5) 返回值 2. 第二问: 背包恰好装满3. 空间优化 416.分割等和子集1. 状态表示2. 状态转移方程3. 初始化4. 填表顺序5. 返回值 [494. 目标和](https://leetcode.cn/proble…

解锁 DevOps 新境界 :使用 Flux 进行 GitOps 现场演示 – 自动化您的 Kubernetes 部署

前言 GitOps 是实现持续部署的云原生方式。它的名字来源于标准且占主导地位的版本控制系统 Git。GitOps 的 Git 在某种程度上类似于 Kubernetes 的 etcd&#xff0c;但更进一步&#xff0c;因为 etcd 本身不保存版本历史记录。毋庸置疑&#xff0c;任何源代码管理服务&#xf…

将Docker镜像变为可执行文件?体验docker2exe带来的便捷!

在现代软件开发中,容器化技术极大地改变了应用程序部署和管理的方式。Docker,作为领先的容器化平台,已经成为开发者不可或缺的工具。然而,对于不熟悉Docker的用户来说,接触和运行Docker镜像可能会是一个复杂的过程。为了解决这一问题,docker2exe项目应运而生。它提供了一…

IBM BAW(原BPM升级版)使用教程第八讲

续前篇&#xff01; 一、流程开发功能模块使用逻辑和顺序 前面我们已经对 流程、用户界面、公开的自动化服务、服务、事件、团队、数据、性能、文件各个模块进行了详细讲解&#xff0c;现在统一进行全面统一讲解。 在 IBM Business Automation Workflow (BAW) 中&#xff0c;…

针对共享内存和上述windows消息机制 在C++ 和qt之间的案例 进行详细举例说明

针对共享内存和上述windows消息机制 在C++ 和qt之间的案例 进行详细举例说明 以下是关于在 C++ 和 Qt 中使用共享内存(QSharedMemory)和 Windows 消息机制(SendMessage / PostMessage)进行跨线程或跨进程通信的详细示例。 🧩 使用 QSharedMemory 进行进程间通信(Qt 示例…

jetson orin nano super AI模型部署之路(十)使用frp配置内网穿透,随时随地ssh到机器

为什么要内网穿透&#xff1f; 我们使用jetson设备时&#xff0c;一般都是在局域网内的电脑去ssh局域网内的jetson设备&#xff0c;但是这种ssh或者VNC仅限于局域网之间的设备。 如果你出差了&#xff0c;或者不在jetson设备的局域网内&#xff0c;想再去ssh或者VNC我们的jet…