贰叁肆 - 学习笔记
type: channel
link: https://www.ersansi.top/index.php/category/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/
description: 各种学习笔记
items: Python-Web应用- Blueprint（蓝图）
items: Python-Web应用-页面组合/CSS引用
items: Python-Web应用-界面跳转
items: Python-Web应用-显示一个html页面
items: 利用iframe标签实现局部刷新
items: Centos Bash脚本
items: 网络工程师总结
items: 网络工程师——无线局域网
items: 网络工程师——以太网通道
items: 网络工程师——生成树协议-STP

Python-Web应用- Blueprint（蓝图）
type: item
date: 2026-05-16T14:54:00+08:00
description: 简介 蓝图对大型项目来说是非常友好的，可以很方便的维护对应的模块 例如一个app.py文件里面包含了几十上百条路由，这些路由对应的模块是不同的，如果需要维护其中一个模块的路由，就需要在这几十上百条路由中慢慢找，如果使用了蓝图，那么直接在对应模块的蓝图中修改维护即可。 创建蓝图 创建py文件 每个蓝图都是一个单独的py文件，否则就失去了蓝图的意义 在app.py同级目录下创建一个新的py文件，文件名称可以根据模块名称来定，例如需要创建的是home这个模块的蓝图，那么就创建一个home.py文件 引入Blueprint类 在新创建的py文件中引入blueprint类 from flask import Blueprint 创建蓝图 创建一个名称为home的蓝图，并为其指定静态目录 home_bp = Blueprint('home', __name__, static_folder='static/home', static_url_path='/static/home') home_bp可以理解为一个变量名 Blueprint里面的home是蓝图名 __name__是Python 的模块名变量，代表当前模块（通常是包含该行代码的 .py 文件），Flask 利用它来确定蓝图的根目录，以便找到蓝图自己的 templates 文件夹和 static_folder。通常直接传 name 即可。 static_folder='static/home'是静态文件的实际路径，如果这个蓝图只有路由，没有静态文件（css,js等）可以不要 static_url_path='/static/home'是静态文件的访问URL前缀，通常与实际路径一致，但是注意在前面加/，如果这个蓝图没有静态文件可以不要 蓝图创建完成 蓝图创建完成后就可以在home_bp = Blueprint('home', __name__, static_folder='static/home', static_url_path='/static/home')后面写该模块的路由了 下面是一个简单的蓝图： from flask import Blueprint, render_template home_bp = Blueprint('home', __name__, static_folder='static/home', static_url_path='/static/home') @home_bp.route('/') def home(): return render_template('index.html') 注册蓝图 蓝图创建后需要在需要调用的地方注册才能使用 例如我现在创建的home蓝图，我需要app.py运行后调用这个模块，那么我就需要在app.py里面注册蓝图 首先在文件顶部引入蓝图模块 from home import home_bp from后面的home是模块名称，对应的是蓝图py文件的名称，home_bp是创建蓝图时候的变量 引入蓝图模块后再app = Flask(__name__)下面注册蓝图 app.register_blueprint(home_bp,url_prefix='/') app是应用实例的名称，这个应用实例明在是子再app = Flask(__name__)的时候定义了，如果是home = Flask(__name__)的话，应用实例名称就是home，对应的，就需要把app.register_blueprint(home_bp,url_prefix='/')该成home.register_blueprint(home_bp,url_prefix='/') register_blueprint是 Flask 应用的一个方法，用于将蓝图中定义的所有路由、静态文件配置、模板等合并到主应用中。如果不调用该方法，蓝图中定义的路由将无法访问 home_bp是蓝图模块，再创建蓝图模块的时候定义的 url_prefix='/'是蓝图访问路径，例如现在是/，那么访问ip:5000的时候就访问的是home这个蓝图，如果把/该成/home，那么想要访问这个蓝图的时候就需要访问ip:5000/home 应用对应蓝图的静态文件 在《Python-Web应用-页面组合/CSS引用》中，引用静态文件是 这个引用的是static目录下的静态文件，如果不同模块的静态文件位置不同，每个模块都在蓝图中定义了static_folder='static/home'和static_url_path='/static/home'，那么就可以在static前面加上蓝图模块名称来实现不同模块使用不同的目录下的静态文件，例如： 在static前面加home.

Python-Web应用-页面组合/CSS引用
type: item
date: 2026-05-16T12:47:00+08:00
description: 简介 一个web页面有很多模块，这些模块很多是重复的，这时候就可以通过页面组合来调用，而不是每个页面都重复的写一个模块 例如顶部的导航栏，底部的版权信息等，需要在每个页面都展示的模块，都可以直接组合调用使用，无需重复写 本篇文章基于《Python-Web应用-界面跳转》上修改 创建CSS目录以及模块目录 创建CSS目录 在项目目录下面新建一个名称为static的目录，这个目录用于存放CSS文件 创建模块目录 在templates目录下面创建components目录，这个目录用于存放模块 创建骨架文件 在templates目录下创建一个名称为frame.html的文件，这个文件是一个完整的html文件 这个文件写了一个简单的顶部导航栏 调用了外部CSS 中的{{ url_for('static', filename='style.css')}}是 Flask 模板中用于生成静态文件 URL 的标准写法。 {{...}} {{...}}是Jinja2 模板引擎的变量输出语法，双花括号内的表达式会被计算，结果替换到 HTML 中 url_for() url_for()是Flask 提供的全局函数，用于根据传入的端点（endpoint）和参数反向生成 URL，在模板中可以直接使用，无需额外导入 static static参数是 Flask 内置的特殊端点名称，指向项目的静态文件目录（默认是项目根目录下的 static 文件夹），当使用 url_for('static', filename='...') 时，Flask会生成指向static目录下指定文件的URL，注意static参数是固定的不能改变的，不能说css文件在css目录下，就可以把static改成css CSS不在static目录下 如果css文件不在static目录下，那么有两方法可以解决 第一种，在主程序py文件中指定static的目录和路径 这一种方法很简单，直接在app = Flask(__name__)中添加两个参数，一个是static_folder='/css目录路径'，另外一个是static_url_path='/css目录路径'，然后正常使用href="{{ url_for('static', filename='style.css')}}即可。 第二种是引用蓝图，这种方式适用于大型项目，利用蓝图管理对应模块的路由，css，js等，方便维护，这种方法比较复杂，后面放到单独的一篇文章讲解 filename='style.css' 这个参数是指定css文件，style.css是css文件名称，支持路径方式，例如现在默认的css目录是static，但是你在下面创建了一个css目录，在css目录面创建了一个index.css文件，那么就可以使用指定路径的方式：css/index.css 修改首页（index.html）文件 把之前的index.html文件修改一下，因为创建了骨架文件，这个文件包含了完整的html文件必要模块，那么index.html文件只需要展示首页部分的内容即可 下面就是一个简单的示例文件： {% extends "frame.html" %} {% block title %}首页-测试首页{% endblock %} {% block index_text %} 测试首页 {% endblock %} 第一行{% extends "frame.html" %} {% extends "frame.html" %}是让当前模板采用frame.html也就是创建的骨架文件作为基础布局，只需填写变化的部分。 这是Jinja2实现代码复用、保持页面结构一致的标准方式。 第二行{% block title %}首页-测试首页{% endblock %} 这一行的作用是把首页-测试首页填充进frame.html的完整的html结构里面的 标签里面，或者说是替换骨架文件里面的{% block title %}默认标题{% endblock %} 第三、四、五行 {% block index_text %} 测试首页 {% endblock %} 这几行的作用是把 {% block index_text %} {% endblock %} 中间的内容填充到骨架文件里面 创建底部版权文件 创建底部的版权文件也是一样的，因为骨架文件里面有完整的htnl格式，我们只需要编写填充部分即可 下面是一个简单的示例： 这个是底部 组合页面 回到骨架文件，开始引用填充部分（index.html）以及底部的版权信息模块 {% block title %}默认标题{% endblock %} 选项一 选项二 选项三 {% block index_text %}{% endbloc…

Python-Web应用-界面跳转
type: item
date: 2026-05-15T14:09:00+08:00
description: 简介 在《Python-Web应用-显示一个html页面》中了解了如果显示一个HTML页面，这篇文章将会了解如何跳转到另外一个界面 原理和《Python-Web应用-显示一个html页面》是相同的，都是通过装饰器（路由）切换的 本篇文章以一个登录界面为例，当点击登录的时候跳转到登录界面 创建登录界面 在templates目录下创建一个名称为login.html的文件 新增装饰器（路由） 打开之前的app.py文件，需要在@app.route('/')下面创建一个新的装饰器（路由） @app.route('/login') def login(): return render_template('login.html') 这一段代码的意思为： 当访问127.0.0.1/login的时候执行login函数，这个函数返回的是login.html文件 修改index.html 在之前的index.html文件的 标签下面新增一个标签，标签的herf参数填写/login，标签显示文字内容为登录 登录 测试 浏览器打开127.0.0.1:5000 点击登录即可跳转到登录页面

Python-Web应用-显示一个html页面
type: item
date: 2026-05-15T13:26:00+08:00
description: 简介 本篇文章是使用Python做web应用的开始，将从最简单的显示html页面开始 这里使用的是Flask框架 创建项目目录以及安装Flask 在进行这一步的前提是你已经安装好Python了 创建目录 首先是创建项目目录，项目目录名称没有指定，这个根据实际情况而定，例如我创建的项目目录就是Example 目录结构如下: Example\ |----templates 这并不是一个完整的项目目录，只是我们这篇文章用到的目录结构，为了避免混淆，所以其他目录不创建 上述目录结构中，Example是这个项目的总目录，下面的templates是存放html模板的目录 安装Flask 使用pip命令安装Flask pip install flask 创建index页面 使用你熟悉的编辑器创建index页面，这个页面需要创建在templates目录下面 创建Py文件 在templates目录同级目录下也就是Example目录下创建一个app.py文件，当然，这个文件名并不是固定的，可以自定义 编辑Flask应用代码 下面是一个简单的完整的Flask应用代码 from flask import Flask,render_template app = Flask(__name__) @app.route('/') def home(): # 渲染template目录下的index.html return render_template('index.html') if __name__ == '__main__': app.run(debug=True) from flask import Flask,render_template的作用是从Flask库中导入Flask这个类和render_template这个函数 Flask这个类是用来创建web应用实例 render_template这个函数用来读取并返回html文件 app = Flask(__name__)的作用是创建Flask应用实例 __name__是一个Python内置变量，代表当前模块的名字，如果直接允许这个文件，__name__的值是__main__ Flask需要使用__name__这个参数来定位静态文件（CSS/JS）和模板文件（HTML）所在的文件夹。传入__name__之后，Flask会自动以当前文件所在目录为根目录，去寻找`templates和其他文件夹。 @app.route('/')是一个装饰器，也可以理解为路由，它控制了用户访问那个路径的时候执行那一段代码，例如这里，当用户访问根路径也就是是127.0.0.1:5000/的时候，执行的就是下面的home函数 def home():的作用是定义一个名称为home的函数，这个函数在@app.route('/')下面，当用户访问根路径的时候就会执行这个函数 return render_template('index.html')使用return调用render_template这个函数，参数是index.html，也就是说当home这个函数被调用的时候，执行返回index.html这个页面 if __name__ == '__main__':是判断当前模块是被Python执行还是被导入其他模块中 如果是直接运行python app.py，那么__name__的值等于__main__,当条件成立执行if下面的代码 app.run(debug=True)的作用是启动Flask内置的开发服务器，debug=True是开启调试模式，开启调试模式的好处是当你修改代码的时候，服务器会自动重启，不需要手动重启，但是这个模式在生成环境下是绝对不能使用的，会有安全风险。 启动/访问实例 启动实例 打开cmd命令行，切换到项目目录下，输入下面命令启动实例 python app.py 访问实例 在浏览器中输入127.0.0.1:5000即可访问

利用iframe标签实现局部刷新
type: item
date: 2022-11-13T00:25:00+08:00
description: 简介： iframe标签详细属于以及功能具体请百度，能找到这篇帖子的估计已经对该标签有所了解了，这里不做重复 主页代码： 测试主页 按钮1 按钮2 按钮3 原理： 当按钮被单击时候触发名字为frameB的这个iframe标签，这个标签一开始加载的是0.html，单击按钮2的时候切换加载1.html 第一页代码： 测试页1 测试页1 第二页代码： 测试页2 测试页2 第三页代码： 测试页3 测试页3

Centos Bash脚本
type: item
date: 2022-11-02T22:11:00+08:00
description: 脚本开头： #!/bin/bash 每个脚本的开头都是以这一行开头，用于说明下面的脚本是用什么运行的 输出字符： echo"要输出的字符" 变量： 新建变量： 变量名=赋值 注意： 命名只能使用英文字母，数字和下划线，首个字符不能以数字开头。 中间不能有空格，可以使用下划线 _。 不能使用标点符号。 不能使用bash里的关键字（可用help命令查看保留关键字）。 使用变量： $变量名 使用变量需要在变量名前面加一个美元符号$ 获取键盘输入： read -参数 参数： 参数 作用 -s 安静模式 -r 反斜杠不作为转义字符 -p"需要提示的文本" 用户输入行前面提示 -t 超时时间 指定超时时间，单位为秒 -u 文件描述符 从指定文件描述符读取输入 -e 如果标准输入时从终端来的，未来的readline被采用 -i 文本 如果readline是被采用来读取该行，文本时放置到编辑缓冲区编辑开始之前 例子： 现在运行脚本，需要用户输入“Y”和“N”来做选择，并且提示用户“请输入"Y"确定，输入"N"退出，默认为"N":”,然后把用户的选择赋值到yn变量中。 read -p "请输入"Y"确定，输入"N"退出，默认为"N":" yn 最后的yn为变量名，用户输入的内容会赋值到yn这个变量名中 if判断： if [ 判断条件 ];then 条件符合后执行的操作 elif [ 判断条件 ];then 条件符合后执行的操作 else 以上条件都不符合执行的操作 fi if如果，elif否则如果，else否则，fi结束语句 注意： 如果“=”两边没有空格时赋值，“=”两边有空格为比较 判断条件两头都要有空格 "$abc"="1" #等号两边没有空格为赋值 "$abc" = "1" #等号两边有空格为比较 用户登录时自动执行脚本： 把脚本放到/etc/profile.d目录 自定义脚本启动命令： alias 自定义的命令='输入自定义的命令后执行的操作' 在/etc/bashrc文件最后添加 清屏命令： clear 这个命令将会刷新屏幕，本质上只是让终端显示页向后翻了一页，如果向上滚动屏幕还可以看到之前的操作信息。一般都会用这个命令。 在指定文件最后插入一行或多行： 插入单行： echo "要插入的内容" >> 文件名 注意：echo后面有空格，要插入的内容后面也有空格，>>后面也有空格 插入多行： echo -e "要插入的第一行\n要插入的第二行\n要插入的第三行" >> 文件名 添加参数-e，使用\n换行 删除指定文件的指定行： sed 删除指定行： sed '行数d' 文件名 删除第5行 sed '5d' 文件名 删除最后一行： sed '$d' 文件名 最后一行用美元符号代替 删除第几行到第几行： sed '要删除的第一行,要删除的最后一行d' 文件名 删除第8行到第10行 sed '8,10d' 文件名 删除不连续的行： sed '要删除的行d,要删除的行d,要删除的行d' 文件名 删除第3行，第8行和最后一行 sed '3d,8d,$d' 文件名 除了那几行其他的都要删除： sed '不需要删除的开始行,不需要删除的最后一行!d' 文件名 除了第3行到第6行其他的都要删除 sed '3,6!d' 文件名 删除空白行： sed '/^$/d' 文件名 删除包含特定字符的行： sed '/特地字符/d' 文件名 需要删除包含install这个单词的行 sed '/install/d' 文件名 删除特定字符开头的行： sed '/^特定字符/d' 文件名 需要删除linux开头的行 sed '/^linux/d' 文件名

网络工程师总结
type: item
date: 2022-10-24T19:54:00+08:00
description: 数据表示： 进制表示： 二进制下标是“2”； 十进制下标是“10”，或者后面加字母“D” 八进制下标是“8”，或者后面加字母“O” 十六进制下标是“16”，或者后面加字母“H” 三位二进制等于一位八进制，四位二进制等于一位十六进制 十六进制10=A,11=B,12=C,13=D,14=E,15=F 总结：D十，O八，H十六，三二一八，四二一一十六 源码、反码、补码： 在计算机中，存储一个数用的是补码 最高位为符号位，0表示正数，1表示负数 原码： 没有改动的二进制，范围：-（2的（N次方-1）-1）~2的（N次方-1）-1 反码： 正数表示方法和原码一样不变，负数表示方法除了符号位，其他的和原码相反，范围：-（2的（N次方-1）-1）~2的（N次方-1）-1 补码： 正数表示和原码一样，负数表示方法在反码的数值位加1，符号位不变，范围：-2的（N次方-1）~2的（N次方-1）。 总结：原二进制，反正不改负符不改其他相反，补正不改负符不改其他反加1 逻辑运算： 0=假，1=真 或运算： 无真结果为假，有真结果为真，0+0=0，0+1=1，1+1=1，1+0=1 与运算： 只有两个都为真结果才为真，否则为假，0×0=0，0×1=0，1×0=0，1×1=1 非运算： 不真即假，不假即真 异或运算： 两个条件一致结果为假，两个条件不一致结果为真，0⊕0=0，0⊕1=1，1⊕0=1，1⊕1=0 计算机结构： 总线：数据总线，地址总线：控制总线 CPU: 运算器： 算术逻辑单元ALU：算术逻辑运算 累加寄存器AC：暂存中间的计算的结果 数据缓冲寄存器：保存从主存储中读取的数据 状态条件寄存器：保存计算过程中的状态信息，例如借位，进位，结果溢出 控制器： 程序计数器PC：存放指令所在的地址 指令寄存器IR：保存当前正在执行的指令 指令译码器：对指令操作码译码 时序部件：为指令执行产生时序信号 寻址方式： 指令是由操作码和地址码组的 立即寻址： 操作数在指令中 直接寻址： 地址码中有操作数的地址，可以直接根据地址在内存中找到操作数 间接寻址： 经过两次或以上的访存操作后才能得到操作数 变址寻址： 涉及到变址寄存器 寄存器寻址： 操作数在寄存器中 寄存器间接寻址： 多次访问寄存器得到操作数 CISC与RISC： CISC： 偏向用户编程灵活度，数量多，频率差别大，可变长格式，支持多种寻址方式，使用微程序控制技术 RISC： 偏向机器执行高效性，数量少，频率接近，定长格式，大部分为单周期指令，操作寄存器，只有Load/Store操作内存，支持寻址方式少，增加了通用寄存器，硬布线逻辑控制为主，适合采用流水线，优化编译，有效支持高级语言 流水线： 计算公式： 计算公式：（t₁+t₂+t₃）+（n-1）t₁ t₁、t₂、t₃对应取址、分析、执行的时间，最后一个t₁是周期，也就是这三步中用时最长的那一步的时间 流水线指标： 吞吐率： 吞吐率：Tp=n/Tk,n为任务的数量，Tk是流水线执行完需要的时间 理论最大吞吐率：周期的倒数 加速比： 加速比：S=Ts/Tk，TS是不适用流水线执行完任务的时间，TK是使用流水线执行完所有任务的时间。 效率： 一条指令分三步执行完，当只有第一步在工作的时候，效率为三分之一，当一二步都在工作的时候效率为三分之二，当一二三步都在工作的时候效率为百分之百 存储系统结构： 存储系统有CPU里面的寄存器，缓存（Cache），主存（内存），辅存（磁盘） 速度越快容量越小，距离CPU越近速度越快 速度：寄存器>缓存>主存>辅存 主存：随机存储器RAM（掉电丢失），只读存储器ROM（掉电不丢失） 缓存：Cache高速缓冲存储器，实现缓和CPU和主存之间的速率矛盾 存储系统的存储方式： 顺序存取（磁带） 直接存取（硬盘） 随机存取（内存） 相关联存取（Cache），根据内容存取 主存储器组成： 计算内存： 计算有多少芯片组成：用总容量除以芯片容量 知道开始编址和接收编址求字节：用最大编址减最小编址加1 知道字节求容量：把字节转换为二进制，K=2¹⁰=1024=1K，去掉十个零得到1个K，剩余的转十进制，得到单位为KB的容量，如果要算芯片数，用总容量除以芯片容量。 表示存储容量相关术语： 位：用bit表示，一个二进制表示1bit 字节：用B表示，1B=8bit 字：实际表示CPU以此处理的二进制的位数，通常为字节的整数倍，8/16/32/64bit 磁盘： 时间排序： IDE(PATA)<SATA(6Gbps)<SCSI<SAS<SSD SAS用于高端，NLSAS用于较大数据块，SATA用于较大数据块，FC用于高端用户 RAID技术： 条带化+校验/条带化+镜像 条带：把一块数据分布存放在多块磁盘中。 可以提升性能，保证数据可靠性。 条带…

网络工程师——无线局域网
type: item
date: 2022-10-22T00:11:00+08:00
description: 无线数据网络种类： 无线数据网络分为：无线个人网、无线局域网、无线城域网和无线广域网四大类。 种类 标准 典型应用 覆盖范围 无线个人网（WPAN） IEEE802.15 蓝牙 ≤10米 无线局域网（WLAN） IEEE802.11 无线企业网 ≤100米 无线城域网（WMAN） IEEE802.16 主要用于Interne访问 2-10公里 无线广域网（WMAN） IEEE802.20&3蜂窝移动通信 主要用于Intern访问 2-10公里 无线局域网 无线局域网对应以太网来说，优势主要由四方面： 1、移动性 2、灵活性 3、成本低 4、容易扩充 无线局域网主要标准IEEE802.11，按照接入方式来分的话主要分两种。 有接入点模式： 一种是有接入点的模式，也叫做Infrastructure结构（基础设施结构），有接入点的模式指的是它会有无线接入点AP这一个设备，这一个设备主要作用是把有线信号转为无线信号，把无线信号转为有线信号。 无接入点模式： 另外一种是Ad-hoc结构，也叫无接入点模式，无接入点模式指的是直接在终端域终端之间进行组网，不需要有AP的支持，这一种一般用于临时性的组网，因为Ad-noc模式结构非常的复杂多变，每一个终端它即是终端，也是路由器，而且是动态的保持和其他终端进行连接，在Ad-noc结构中路由器协议的设计和传统路由器协议不一样，它的路由协议的设计会更加复杂。 在企业中用的都是有接入点模式进行组网。 无线局域网标准（WLAN标准）： 标准 运行频率 主要技术 数据速率 IEEE802.11 2.4GHz 扩频通信技术 1Mbps和2Mbps IEEE802.11b 2.4GHz HK-DSSS技术 11Mbps IEEE802.11a 5GHz OFDM调制技术 54Mbps IEEE802.11g 2.4GHz OFDM调制技术 54Mbps IEEE802.11n 2.4GHz和5GHz MIMO和OFDM 600Mbps IEEE802.11ac 5GHz MIMO和OFDM 1Gbps IEEE802.11ax 2.4GHz和5GHz MIMO和OFDM 11Gbps 扩频技术是将要发送的信息扩展到一个很宽的频带上，以很宽的信道传送信息，抗干扰和抗衰减能力强，抗阻塞能力也强。 包括跳频扩频（FHSS）和直连序列扩频（DSSS）。 无线局域网如果工作在2.4GHz这一个频率，IEEE总共会划分出14个信道，每一个信道的频带宽度是22MHz，理论上会有4组互不干扰的信道，但是在中国，14这一个信道并不开放，所以在中国国只有3组互不干扰的信道。 理论上可以使用（1、6、11），（2、7、12），（3、8、13），（4、9、14）这四组互不干扰的信道来进行无线覆盖。 无线局域网IEEE802.11 MAC层协议 在以太网当中，使用CSMA/CD协议来解决介质征用的问题，但是在无线局域网中是不能直接照搬CSMA/CD协议的，因为对于无线局域网而言会存在隐蔽站问题和暴露站问题。 隐蔽站问题： 一下图为例，A的无线信号的范围是有限的，它不能覆盖到C，它可以刚好覆盖到B，同理，C的无线信号的范围也是有限的，覆盖不到A，但是也刚好覆盖到B，这时候A有信息要发给B，它首先会监听到信道处于空闲，当A监听到信道处于空闲状态之后就会给B发送信息，同一时间，C也有信息发送给B，C也监听到信道处于空闲，也给B发了信息，结果信号在B哪里产生了冲突问题。 这就是隐蔽站问题，隐蔽站的问题的根源是A发现不了C，C也发现不了A，这在以太网中式不存在这一种状况的。 暴露站问题： B的覆盖范围可以覆盖到A和C，C的覆盖范围可以覆盖到B和D，现在B有信息要发给A，监听到信道式空闲的，B就把信息发出去了，同时C有信息要发送给D，由于B发给A的这个信号向四周扩散的，那么C就会监听到信道处于忙碌状态，导致C不敢把信息发给D，实际上B给A发的同时C给D发是没有问题的。 隐蔽站与暴露站总结： 隐蔽站问题：检测信道空闲但实际上并不空闲 暴露站问题：检测信道忙碌但实际上并不忙碌 在无线局域网中不能使用CSMA/CD协议的，而是只能使用改进的CSMA协议，也就是CSMA/CA协议，CA指的是冲突避免，冲突避免并不是完完全全的避免冲突，只是把冲突的概率降到最低，因为CSMA/CA协议的话会增加一个退避计时器和一个停止等待协议，把这个通途的概率降到最低而已。 MAC层协议： IEEE802.11在MAC层它定了两个子层，一个是DCF，叫分布协调功能，还有一个叫PCF，也叫点协调功能。 分布协调功能定义的是争用服务，用的就是CSMA/CA协议，它是在每一个节点使用CSMA机制的分布式接入算法，让各个站通过争用信道来获取发送权。 点协调功能PCF使用集中控制的接…

网络工程师——以太网通道
type: item
date: 2022-10-21T20:44:00+08:00
description: 以太网通道 以太网通道又叫聚合链路，也叫端口聚合，在华为中又叫做eth-twunk 以上图为例，有一台交换机A，交换机A下面连接10个用户，也就是10台PC，每个用户的带宽是100Mbps，交换机B下面也是有10个用户，每个用户的带宽也是100Mbps，用一条1000Mbps的链路把两条交换机连接起来，在这种情况下，A这边的用户与B这边的用户在网络高峰期通信的时候，没有网络瓶颈的问题，因为1000Mbps的带宽足以支撑A的用户和B的用户相互通信。 以上图为例，现在A这边的用户扩充到20个，B这边的用户也扩充到20个，两台交换机之间的链路还是1000Mbps，现在两台交换机相互连接的这一条带宽已经不够用了，有两种方法解决这一个问题。 第一种方法是把A交换机和B交换机的相连的端口模块更换成万兆的模块，并且把链路也更换成万兆的链路，这一种方法可以解决网络瓶颈的问题，但是网络可靠性没有提高，因为一旦万兆链路断开了或者是两边的交换机其中一台的万兆模块故障了，那么两边的用户是无法通信的。 另外一种方法成本比第一种更低，而且可以保证网络的可靠性，第二种方案就是链路聚合，所谓的链路聚合指的是把多条物理链路捆绑成一条逻辑链路。 既然一条100Mbps的不够用，那么在拉一条，但是直接拉的话会有问题，很明显已经产生了交换环路，由于生成树协议的介入，它必然会阻塞一条链路，也就是说带宽没有得到提升，只是可靠性得到了保证。 在做链路聚合的时候，首先在两台交换机中间再拉一条链路，再用链路聚合把多条物理链路捆绑成一条逻辑链路，捆包之后，生成树协议去看中间的链路是会把它当作一条逻辑链路，不会认为有环路的存在，两条1000Mbps的带宽叠加之后变成了2000Mbps，可以满足用户的互联互通。 而且两条物理链路，其中一条断开了，另外一条仍然可以使用，可靠性也是有所保证的。 链路聚合捆绑规则： 1、参与捆绑的端口必须属于同一个VLAN。 2、如果端口配置的是中继模式，那么应该再链路两端将通道中的所有端口配置成相同的中继模式。 3、所有参与捆绑的端口的物理参数设置必须相同。 协议： 链路聚合一种方式是手动，就是由网络管理员创建聚合组，哪一些端口和链路加入聚合组，完全由网络管理员控制，不需要聚合协议。 第二种方法就是用到聚合协议，思科由端口聚合协议，思科的是独有的，不开放的。另外一个是IEEE802.3ad制定出来的LACP（链路聚合控制协议），如果使用了链路聚合协议，再进行链路聚合的时候是非常方便的，只要在交换机上的端口开启这一功能，聚合组的常见和哪一些端口加入聚合组完全是由协议控制的，不需要网络管理员的干预，并且可以降低出错率。

网络工程师——生成树协议-STP
type: item
date: 2022-10-20T21:38:00+08:00
description: 冗余 对于一个企业来说，网络的可靠性是至关重要的，因为网络一旦出现问题会给企业的生产经营带来非常大的损失，想要保证网络的可靠性，要么就是靠冗余设备，要么就是冗余链路，所以一定会提到冗余这个词，因为任何一台设备你都不能保证它可以一直正常工作，它总有宕机的一个时间，所以就需要冗余化的一个设计来保证网络的可靠性。 以上图为例，这一种方案就是没有冗余设计的，一旦两台交换机间的线路断开，PCA和PCB就无法通信了。 为了提高这种网络的可靠性就需要冗余设备或者冗余链路的方案来解决这个问题了。 广播风暴： 我们可以在添加一台交换机C，一旦i骄傲还击A和交换机B的链路断开了，还可以通过交换机C来进行通信，以下图为例。 但是这一种设计要考虑环路问题，这一种设计已经形成了交换环路，也就是物理环路。 交换环路会带来广播风暴这一问题，广播风暴指的是在整个网络当中不断转发广播信息，使交换机处于极度忙碌的章台，主机也被迫接收广播帧，会出现网络速度慢甚至死机的现象。 广播风暴的产生及危害： 广播风暴的产生除了个别网卡故障一直在发送广播帧以外，环路问题也是一个最大的原因。 以上图为例，PCA肯定会有一个IP地址，例如192.168.1.2，PCB肯定也会有一个IP地址，例如192.168.1.3，现在PCA和PCB进行通信，例如PCA去pingPCB，在整个局域网内部寻址的话，是要找到PCB所对应的MAC地址，用MAC地址来封装IP数据包，MAC地址在PCA主机里面会有一个ARP表，如果表里面没有PCB对应的MAC地址的话，那么PCA会发一个在正常不过的广播消息，就是ARP广播，ARP广播是很正常的广播，这个ARP广播到达交换机A之后，A会转发这一个广播消息，会往交换机B和交换机C转发，交换机C收到之后又往交换机B和交换机A转发，同理，交换机B收到之后又向交换机A和交换机C转发，主机也不断的接收到广播帧，这就形成了广播风暴，并且会形成双相的广播风暴，处于广播风暴后，交换机也会一直不断的转发广播帧，正常用户通信会被阻塞，PCB也是被迫的不断处理广播帧，导致它的网络速度非常慢甚至死机，这是第一个危害。 第二个危害是帧复制，第三个危害是MAC地址表不稳定。 因为交换机在寻址的时候靠的是MAC地址和端口的映射表，MAC地址和端口的映射表是通过读取帧的源MAC地址和进入端口来学习的，例如交换机A首先获取的MAC地址和端口是PCA的，这一个帧交换机A转发给交换机B，交换机B转发给交换机C，交换机C在转发给交换机A，实际上是同一个帧，它的源MAC还是PCA的，但是帧进入的端口不同了，原来的MAC表的条目会被替换掉。 而且这是两个方向的广播帧，交换机A转发给交换机C，交换机C在转发给交换机B，交换机B又转发给交换机A，那这个时候帧进入的端口又不一样了，映射表又变了，这样的话这MAC映射表条目会一直被替换，MAC映射表不稳定，正常用户的数据帧是无法进行转发的。 这样设计看起来是提高了网络的冗余度，但是实际上是有问题的，不仅没有实现网络可靠性，还会给网络带来广播风暴。 生成树协议-STP 想要解决交换机环路产生广播风暴这个问题就需要用到了生成树协议-STP。 STP协议功能： STP——Spanning Tree Protool（生成树协议） 逻辑上断开环路，防止广播风暴的产生，这俄格逻辑上的计算是根据交换机和交换机之间传递的桥数据单元来进行生成树协议它的一个计算，通过计算之后它会断开某一条链路，避免环路的存在，防止广播风暴的产生。 当链路出现故障，断开的接口激活，恢复通信，起备份线路的作用。 例如仙子啊PCA要和PCB通信，正常情况是交换机C直接转发给交换机A，交换机B是冗余设备。 首先三台交换机开启生成树协议，进行桥数据单元的信息交换，进行生成树协议的信息计算，计算完成后假设断开的是C交换机和B交换机相连的这一条链路，这种情况下，PCA和PCB通信就会通过交换机B转发，实现网络可靠性方面的一个保证，又不会造成交换环路。 STP协议算法： 生成树协议是断开交换机B上面的交换机B和交换机C相连的端口。 STP将一个环形网络生成无环形网络，它的步骤分为三步。 1、选择根网桥（Root Bridge）：生成树协议诞生的较早，在网桥时代，网桥就是交换机的前生，由于STP是在网桥的基础上开发的，因此现在在交换机的网络中仍然沿用网桥这一术语。第一步选择根网桥其实就是选择根交换机； 2、选择根端口（Root Ports）； 3、选择指定端口（Designated Ports）：有些端口不是根端口，就要把它处于阻塞状态； 选择根网桥： 把环形拓扑变成无环拓扑，首先要选出根网桥，根网桥是根据网桥ID来选择的，网桥ID是唯一的，交换机之间传递BPDU，然后选择BID（网桥ID）值最小的交换机作为…