【小沐学OpenGL】Ubuntu环境下glfw的安装和使用
文章目录
- 1、简介
- 1.1 OpenGL简介
- 1.2 glfw简介
- 2、安装glfw
- 2.1 直接命令二进制安装
- 2.2 源码安装
- 3、测试glfw
- 3.1 测试1,glfw+glew
- 3.2 测试2,glfw+glad
- 3.3 测试3
- 结语
1、简介
1.1 OpenGL简介
OpenGL作为图形界的工业标准,其仅仅定义了一组2D和3D图形接口API,而对于窗口管理、IO消息响应等并没有规定。也就是说,OpenGL依赖各平台提供用于渲染的context以及具体实现方式,而各平台提供的实现不尽相同。这些实现主要有:Windows平台下的WGL、Linux下的Mesa/GLX、Mac OS X下的Cocoa/NSGL,以及跨平台的GLUT、GLFW、SDL等等。
安装OpenGL库:
sudo apt-get install build-essential
sudo apt-get install libgl1-mesa-dev
使用如下的命令来查看对应显卡的OpenGL版本:
glxinfo | grep -i opengl
1.2 glfw简介
GLFW 是一个开源的多平台库,适用于 OpenGL、OpenGL ES 和 桌面上的 Vulkan 开发。它提供了一个简单的 API 来创建 窗口、上下文和表面,接收输入和事件。
GLFW 是用 C 语言编写的,支持 Windows、macOS、Wayland 和 X11。
GLFW 根据 zlib/libpng 许可证获得许可。
https://www.glfw.org/
查看glfw安装情况如下:
locate glfw
2、安装glfw
2.1 直接命令二进制安装
使用包管理器安装。
- 安装glfw:
sudo apt-get update
sudo apt-get -y install libglfw3# 或者
sudo apt-get install libglfw3
sudo apt-get install libglfw3-dev# 或者
sudo apt update
sudo apt -y install libglfw3
- 卸载glfw
# 要仅卸载包libglfw3
sudo apt-get remove libglfw3# 卸载 libglfw3 及其依赖项
sudo apt-get -y autoremove libglfw3# 删除 libglfw3 配置和数据
sudo apt-get -y purge libglfw3
2.2 源码安装
官方地址:
https://github.com/glfw/glfw
从 GLFW 的官方网站下载源代码并编译安装,依次执行如下命令:
# git clone git@github.com:glfw/glfw.git
# wget https://github.com/glfw/glfw/archive/refs/tags/3.4.tar.gz
wget http://github.com/glfw/glfw/releases/download/3.4/glfw-3.4.zip
cd glfw-3.4
mkdir build && cd build
sudo apt-get install libxrandr-dev
sudo apt-get install libxinerama-dev
sudo apt-get install libxcursor-dev
sudo apt-get install libxi-dev
cmake .. -DGLFW_BUILD_WAYLAND:BOOL=OFF
make -j4
sudo make install
通过wget下载glfw源码。
通过cmake编译glfw代码。
通过make install安装glfw库文件。
3、测试glfw
3.1 测试1,glfw+glew
要在 Linux 系统上配置 OpenGL 开发环境并使用 GLFW 和 GLEW,你可以按照以下步骤操作。
使用 GLEW 加载所有 OpenGL 函数指针。通过cmake构建测试工程。
- CMakeLists.txt
cmake_minimum_required(VERSION 2.8.1)project(my_project)find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(glfw3 REQUIRED)add_executable(main main.cpp)
target_link_libraries(main OpenGL::GL GLEW::GLEW glfw)
- main.cpp
#include <GL/glew.h>
#include <GLFW/glfw3.h>int main(void)
{GLFWwindow* window;/* Initialize the library */if (!glfwInit())return -1;/* Create a windowed mode window and its OpenGL context */window = glfwCreateWindow(640, 480, "Hello World, yxy", NULL, NULL);if (!window){glfwTerminate();return -1;}/* Make the window's context current */glfwMakeContextCurrent(window);if(glewInit() != GLEW_OK){std::cerr << "Failed to initalize GLEW" << std::endl;return -1;}/* Loop until the user closes the window */while (!glfwWindowShouldClose(window)){/* Render here */glClear(GL_COLOR_BUFFER_BIT);glClearColor(0, 1, 0, 1);/* Swap front and back buffers */glfwSwapBuffers(window);/* Poll for and process events */glfwPollEvents();}glfwTerminate();return 0;
}
编译如下:
3.2 测试2,glfw+glad
GLAD 是一个用于加载 OpenGL 函数指针的库,它简化了 OpenGL 函数的调用。你可以从 GLAD 的官方网站下载并生成适合你需求的 GLAD 配置。通常,你需要指定 OpenGL 的版本和配置文件类型(通常是核心模式)。生成后,将包含的头文件和源文件添加到你的项目中。
在你的项目中,你需要包含 GLAD 和 GLFW 的头文件,并链接到相应的库。如果你使用 CMake,你可能需要在你的 CMakeLists.txt 文件中添加相应的链接指令。
- CMakeLists.txt
cmake_minimum_required(VERSION 2.8.1)project(my_project)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 14)find_package(glfw3 REQUIRED)file(GLOB SOURCE_FILES glad.c main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})target_link_libraries(${PROJECT_NAME} glfw)
- main.cpp
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);int main() {// Intialize GLFWglfwInit();// Configure GLFW (v3.3)glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// Create a window objectGLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL, yxy", NULL, NULL);if (window == NULL) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}// Make our window the main context on the current threadglfwMakeContextCurrent(window);// Initialize GLADif (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return -1;}// Set size of the rendering window (dimensions)glViewport(0, 0, 800, 600);// Register a callback function on the window that gets called// each time the window is resizedglfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// Render loop that keeps on running until we tell GLFW to stopwhile(!glfwWindowShouldClose(window)) {// Check input close window if it is the escape keyprocessInput(window);// Rendering commands here// Set a color to clear the screen with (state-setting function)glClearColor(0.2f, 0.3f, 0.3f, 1.0f);// Clear the screen with the color (state-using function)glClear(GL_COLOR_BUFFER_BIT);// Swap the color buffer and show output to the screenglfwSwapBuffers(window);// Check if any events are triggeredglfwPollEvents();}// Clean/delete all GLFW's resourcesglfwTerminate();return 0;
}void framebuffer_size_callback(GLFWwindow* window, int width, int height) {// Update width and heightglViewport(0, 0, width, height);
}void processInput(GLFWwindow *window) {// Check whether the user has pressed the escape key and close GLFWif (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}
编译如下:
3.3 测试3
- CMakeLists.txt
cmake_minimum_required(VERSION 2.8.1)project(my_project)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 14)find_package(glfw3 REQUIRED)file(GLOB SOURCE_FILES glad.c main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})target_link_libraries(${PROJECT_NAME} glfw)
- main.cpp
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;// 顶点着色器,GLSL语言
const char *vertexShaderSource = "#version 330 core\n""layout (location = 0) in vec3 aPos;\n""void main()\n""{\n"" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n""}\0";
// 片元着色器
const char *fragmentShaderSource = "#version 330 core\n""out vec4 FragColor;\n""void main()\n""{\n"" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n""}\n\0";int main()
{// glfw: initialize and configureglfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif// glfw window creationGLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL, yxy", NULL, NULL);if (window == NULL){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// glad: load all OpenGL function pointersif (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}// build and compile our shader program// ------------------------------------// vertex shaderint vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);// check for shader compile errorsint success;char infoLog[512];glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;}// fragment shaderint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glCompileShader(fragmentShader);// check for shader compile errorsglGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;}// link shadersint shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);// check for linking errorsglGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);float vertices[] = {-0.5f, -0.5f, 0.0f, // left0.5f, -0.5f, 0.0f, // right0.0f, 0.5f, 0.0f // top};unsigned int VBO, VAO;//创建VAO对象glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);//创建VBO对象,把顶点数组复制到一个顶点缓冲中,供OpenGL使用glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO); // 缓冲绑定到GL_ARRAY_BUFFERglBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 顶点数据复制到缓冲的内存中//解释顶点数据方式glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); // 顶点数据的解释glEnableVertexAttribArray(0);// 解绑VAOglBindVertexArray(0);// 解绑VBOglBindBuffer(GL_ARRAY_BUFFER, 0);// render loop// -----------while (!glfwWindowShouldClose(window)){// input// -----processInput(window);// render// ------glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);// draw our first triangleglUseProgram(shaderProgram);glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 3);glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resourcesglDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteProgram(shaderProgram);glfwTerminate();return 0;
}//键盘按键回调函数
void processInput(GLFWwindow *window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}//调整窗口大小回调函数
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height);
}
结语
如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;
╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;
o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;
(✿◡‿◡)
感谢各位大佬童鞋们的支持!
( ´ ▽´ )ノ ( ´ ▽´)っ!!!
相关文章:

【小沐学OpenGL】Ubuntu环境下glfw的安装和使用
文章目录 1、简介1.1 OpenGL简介1.2 glfw简介 2、安装glfw2.1 直接命令二进制安装2.2 源码安装 3、测试glfw3.1 测试1,glfwglew3.2 测试2,glfwglad3.3 测试3 结语 1、简介 1.1 OpenGL简介 OpenGL作为图形界的工业标准,其仅仅定义了一组2D和…...

[数据集][目标检测]汽油检泄漏检测数据集VOC+YOLO格式237张2类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):237 标注数量(xml文件个数):237 标注数量(txt文件个数):237 标注类别…...

图文解析保姆级教程:Postman专业接口测试工具的安装和基本使用
文章目录 1. 引入2. 介绍3. 安装4. 使用 此教程摘选自我的笔记:黑马JavaWeb开发笔记16——请求(postman、简单参数、实体参数、RequestParam映射)想要详细了解更多有关请求各种参数介绍的知识可以移步此篇笔记。 1. 引入 在当前最为主流的开…...

jenkins配置流水线
新建任务,随便选一个名字,选中流水线 配置git的用户名和密码,记录ID,后面配置流水线的时候用。 pipeline {agent anystages {stage(stop app){steps {script {def remote [:]//配置服务地址,用户名和密码remote.na…...

SQL 编程基础
SQL(结构化查询语言)广泛应用于数据库操作,是每个程序员都需要掌握的技能之一。这篇文章将带你从基础入门,了解SQL编程中的常量、变量及流程控制语句。我们将采用简单易懂的语言,结合实际示例,帮助你轻松理…...

sql 中名字 不可以 包含 mysql中 具有 特定意义 的单词
这种sql执行不报错 这种sql执行报错 所以sql中名字不可以使用mysql中具有特定意义的单词 以此文章作为警告,我下次起名字不可以使用 mysql中具有特殊意义的字符 就因为这个导致我搞了一个多小时,急死我了,周五就要前后端联调了。下次千万不…...

分布式部署①
📑打牌 : da pai ge的个人主页 🌤️个人专栏 : da pai ge的博客专栏 ☁️宝剑锋从磨砺出,梅花香自苦寒来 1. 需要部署的服务 Nacos 理论上,应…...
开源可视化大屏superset Docker环境部署
superset 开源可视化大屏Docker环境部署 前言 superset是俄罗斯开源的一款可视化大屏,用于数据可视化探索,含有丰富的图表组件,可以支持接入各种数据源。 接触superset就是想体验下可视化大屏功能,想最快速度安装成功ÿ…...

tomato靶场通关攻略
1.御剑2014找到IP地址 2.dirb扫描目录 3.再次详细扫描目录 4.访问找到的目录文件 进入antibots中 5.搜寻一会再info.php里面发现有东西 6.这个地方貌似可以进行利用 7.查看源代码发现包含include文件上传漏洞 8.网址后面跟?image../../../../../../../etc/passwd 9.既然可以查…...
【Spring Boot 3】【Web】处理跨域资源共享 CORS
【Spring Boot 3】【Web】处理跨域资源共享 CORS 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术…...

HUAWEI华为MateBook B5-420 i5 集显(KLCZ-WXX9,KLCZ-WDH9)原装出厂Windows10系统文件下载
适用型号:KLCZ-WXX9、KLCZ-WDH9 链接:https://pan.baidu.com/s/12xnaLtcPjZoyfCcJUHynVQ?pwdelul 提取码:elul 华为原装系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、华为浏览器、Office办公软件、华为…...
算法练习题10:leetcode76最小覆盖子串-滑动窗口
目录 题目 题目描述 约束条件 解决思路 代码 getOrDefault(c, 0) 方法 方法签名 参数 返回值 示例 getOrDefault 与 get 的主要区别 Integer 题目 题目描述 给定两个字符串 s 和 t,请你在字符串 s 中找到包含 t 中所有字符的最小子串。 要求…...
Svn常用操作技巧详细说明
TortoiseSVN是一个Windows操作系统下的Subversion客户端,它为用户提供了直观易用的界面,方便进行版本控制操作。下面是一些TortoiseSVN的常用操作技巧的详细说明: 检出代码: 在Windows资源管理器中,选择一个空文件夹&a…...

六、MySQL高级—架构介绍(1)
🌻🌻 目录 一、Mysql 简介1.1 概述1.2 Mysql 高手是怎样炼成的 二、Mysql Linux 版的安装2.1 mysql5.52.2 mysql5.7 三、Mysql 的用户与权限管理3.1 MySQL的用户管理3.2 权限管理3.3 通过工具远程访问 四、 Mysql的一些杂项配置(了解)五、 Mysql 逻辑架构…...

TensorRT-For-YOLO-Series项目:实现yolov10模型的python-tensorrt推理(对比int8与fp16推理差异)
项目地址:https://github.com/Linaom1214/TensorRT-For-YOLO-Series/tree/cuda-python 算法支持状态: 2024.6.16 Support YOLOv9, YOLOv10, changing the TensorRT version to 10.0 2023.8.15 Support cuda-python 2023.5.12 Update 2023.1.7 support YO…...

码上君量化互助社群介绍
写在前面 量化投资是一个漫长的过程,一个人单打独斗会走很多弯路,所以建立一个交流沟通互助群是有必要的。 无论是加入我的这个量化互助社群,还是加入其他的社群,首先要想想自己加入社群的目的是什么,自己想从中获得…...

Qt使用小技巧之按钮动态变化
前言 最近写小demo中无意发现的,是想实现当鼠标悬停到按钮上面的时候,按钮实现动态变化,让人知道鼠标经过了按钮,效果如下 hoverDynamicPushButton 正文 首先是将按钮的边框给去掉,然后设置下它的悬停伪状态就行了 格…...
MySQL——事务与存储过程(三)存储过程的使用(1)调用存储过程
使用存储过程可以使程序执行效率更高、安全性更好,增强程序的可重用性和维护性。接下来将针对存储过程的使用进行详细的讲解。 存储过程有多种调用方法。存储过程必须使用CALL语句调用,并且存储过程和数据库相关,如果要执行其他数据库…...

基于VUE2-dataV和echarts实现的可视化大屏,百分比适配PC端
可视化平台中,数据分别通过仪表盘、环状图、柱形图、曲线图、 滚动表格等多种形式展示数据变化。 可视化平台大致分为左、中、右三部分,左侧由能耗总览、耗能 占比、库存预警构成,中间由数据总览、销售计划完成率构成,右侧 由销售…...

FastAPI模块化:为复杂应用程序提供清晰的结构
开题描述: 在现代软件开发中,随着应用程序规模的扩大和功能的增加,传统的单体架构逐渐暴露出其局限性。FastAPI,作为一款高性能的现代Web框架,通过其模块化设计提供了一种解决方案。本文将探讨FastAPI模块化如何为构建…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...

云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
书籍“之“字形打印矩阵(8)0609
题目 给定一个矩阵matrix,按照"之"字形的方式打印这个矩阵,例如: 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为:1,…...

2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...