当前位置: 首页 > news >正文

使用 Qt GRPC 构建高效的 Trojan-Go 客户端:详细指南

  • 使用 Qt GRPC 构建高效的 Trojan-Go 客户端:详细指南
    • 初识 Qt 和 gRPC
      • 什么是 Qt?
      • 什么是 gRPC?
    • 项目结构概述
    • 创建 proto 文件定义 API
      • 下载 api.proto 文件
      • 解析 proto 文件
        • 1. packageoption 语句
        • 2. 消息类型定义
          • Traffic
          • Speed
          • User
          • UserStatus
          • GetTrafficRequestGetTrafficResponse
          • ListUsersRequestListUsersResponse
          • GetUsersRequestGetUsersResponse
          • SetUsersRequestSetUsersResponse
        • 3. 服务定义
          • TrojanClientService
          • TrojanServerService
    • 配置 CMake 构建系统
      • CMake 配置解析
    • 实现 Trojan-Go 客户端
      • main.cpp 内容
      • 代码详解
      • 使用定时器实现数据流量和速度监控
    • 总结

在这里插入图片描述
trojan-go client
在这里插入图片描述

使用 Qt GRPC 构建高效的 Trojan-Go 客户端:详细指南

在上一篇 使用gRPC C++创建动态库以获取Trojan-go客户端的流量和速度信息 文章中使用纯 C++,这次随着 qt6.8 lts 发布,Qt GRPC 作为稳定模块推出,借此机会使用 Qt GRPC 实现该功能。

初识 Qt 和 gRPC

什么是 Qt?

Qt 是一个跨平台的 C++ 框架,用于开发图形界面和非图形界面应用。它提供了丰富的库支持、良好的跨平台兼容性、自动化的信号槽机制,使得在大型应用程序中管理事件和响应更为便捷。在本文中,Qt 提供了自动化工具来简化 Protobuf 和 gRPC 的代码生成,并结合 Qt 的 gRPC 模块,使得构建 gRPC 客户端更加便捷。

什么是 gRPC?

gRPC 是一种高性能的 RPC 框架,由 Google 开发,用于实现不同语言之间的服务调用。其基于 HTTP/2 协议,利用 Protocol Buffers(Protobuf)作为接口描述语言来定义服务和数据结构,允许客户端和服务器之间的轻量化通信。gRPC 的优势在于它的跨平台支持、灵活性和良好的性能,广泛应用于微服务架构和物联网领域。


项目结构概述

在创建项目之前,我们先来定义项目的目录结构,以确保文件结构清晰、便于管理:

trojan-go
├── api.proto          # Protobuf 文件,用于定义 gRPC 服务和消息格式
├── CMakeLists.txt     # CMake 构建文件,配置了编译选项、依赖项
└── main.cpp           # 主程序文件,实现客户端功能
  • api.proto:包含 API 的 gRPC 服务定义和数据结构。
  • CMakeLists.txt:配置 CMake 构建系统。
  • main.cpp:实现了 Trojan-Go 客户端的主要逻辑。

强制依赖 protoc.exe ,需要添加到环境变量中,从 https://github.com/protocolbuffers/protobuf/releases/download/v28.3/protoc-28.3-win64.zip 下载。


创建 proto 文件定义 API

proto 文件定义了客户端与服务器之间的通信规则。我们将在 api.proto 文件中定义数据结构和 gRPC 服务接口,确保客户端和服务器之间能够准确传递数据。

下载 api.proto 文件

下载 trojan-go api.proto 文件,文件内容如下:

syntax = "proto3";package trojan.api;
option go_package = "github.com/p4gefau1t/trojan-go/api/service";message Traffic {uint64 upload_traffic = 1;uint64 download_traffic = 2;
}message Speed {uint64 upload_speed = 1;uint64 download_speed = 2;
}message User {string password = 1;string hash = 2;
}message UserStatus {User user = 1;Traffic traffic_total = 2;Speed speed_current = 3;Speed speed_limit = 4;int32 ip_current = 5;int32 ip_limit = 6;
}message GetTrafficRequest {User user = 1;
}message GetTrafficResponse {bool success = 1;string info = 2;Traffic traffic_total = 3;Speed speed_current = 4;
}message ListUsersRequest {}message ListUsersResponse {UserStatus status = 1;
}message GetUsersRequest {User user = 1;
}message GetUsersResponse {bool success = 1;string info = 2;UserStatus status = 3;
}message SetUsersRequest {enum Operation {Add = 0;Delete = 1;Modify = 2;}UserStatus status = 1;Operation operation = 2;
}message SetUsersResponse {bool success = 1;string info = 2;
}service TrojanClientService {rpc GetTraffic(GetTrafficRequest) returns(GetTrafficResponse){}
}service TrojanServerService {// list all usersrpc ListUsers(ListUsersRequest) returns(stream ListUsersResponse){}// obtain specified user's inforpc GetUsers(stream GetUsersRequest) returns(stream GetUsersResponse){}// setup existing users' configrpc SetUsers(stream SetUsersRequest) returns(stream SetUsersResponse){}
}
解析 proto 文件

这个 api.proto 文件定义了用于 Trojan API 的 gRPC 服务和消息结构,描述了客户端与服务器之间的通信模式。以下是该文件的详细解释:

1. packageoption 语句
package trojan.api;
option go_package = "github.com/p4gefau1t/trojan-go/api/service";
  • package 声明了 proto 文件的包名,trojan.api 用于在生成的代码中作为命名空间。
  • option go_package 定义了用于 Go 语言生成代码的包名,便于 Go 项目中导入。
2. 消息类型定义
Traffic
message Traffic {uint64 upload_traffic = 1;uint64 download_traffic = 2;
}
  • Traffic 消息定义了用户的上传和下载流量,字段类型为 uint64 表示无符号 64 位整数,适合表示较大的流量数据。
Speed
message Speed {uint64 upload_speed = 1;uint64 download_speed = 2;
}
  • Speed 消息记录了上传和下载速度,同样使用 uint64 类型来表示。
User
message User {string password = 1;string hash = 2;
}
  • User 消息包含用户的密码和哈希值,用于用户身份验证或标识。
UserStatus
message UserStatus {User user = 1;Traffic traffic_total = 2;Speed speed_current = 3;Speed speed_limit = 4;int32 ip_current = 5;int32 ip_limit = 6;
}
  • UserStatus 消息表示用户的状态信息,包含用户数据 (User)、总流量 (Traffic)、当前和限制速度 (Speed)、当前和限制的 IP 数量。
GetTrafficRequestGetTrafficResponse
message GetTrafficRequest {User user = 1;
}message GetTrafficResponse {bool success = 1;string info = 2;Traffic traffic_total = 3;Speed speed_current = 4;
}
  • GetTrafficRequest 包含 User 数据,用于请求流量信息。
  • GetTrafficResponse 返回请求状态 success、信息 info,以及流量数据和速度数据。
ListUsersRequestListUsersResponse
message ListUsersRequest {}message ListUsersResponse {UserStatus status = 1;
}
  • ListUsersRequest 不含字段,用于请求用户列表。
  • ListUsersResponse 返回每个用户的状态信息。
GetUsersRequestGetUsersResponse
message GetUsersRequest {User user = 1;
}message GetUsersResponse {bool success = 1;string info = 2;UserStatus status = 3;
}
  • GetUsersRequest 请求特定用户的信息。
  • GetUsersResponse 返回状态 success、信息 info 和用户状态 UserStatus
SetUsersRequestSetUsersResponse
message SetUsersRequest {enum Operation {Add = 0;Delete = 1;Modify = 2;}UserStatus status = 1;Operation operation = 2;
}message SetUsersResponse {bool success = 1;string info = 2;
}
  • SetUsersRequest 包含 UserStatusOperation,用于增加、删除或修改用户。
  • SetUsersResponse 返回操作状态 success 和相关信息 info
3. 服务定义
TrojanClientService
service TrojanClientService {rpc GetTraffic(GetTrafficRequest) returns(GetTrafficResponse){}
}
  • 定义 GetTraffic RPC 方法,允许客户端请求其流量信息。
TrojanServerService
service TrojanServerService {// list all usersrpc ListUsers(ListUsersRequest) returns(stream ListUsersResponse){}// obtain specified user's inforpc GetUsers(stream GetUsersRequest) returns(stream GetUsersResponse){}// setup existing users' configrpc SetUsers(stream SetUsersRequest) returns(stream SetUsersResponse){}
}
  • TrojanServerService 包含 3 个方法:
    • ListUsers:返回用户列表,使用数据流式响应。
    • GetUsers:获取特定用户信息,支持流式请求和响应。
    • SetUsers:修改用户信息,通过流式请求和响应实现。

这个 api.proto 文件定义了 Trojan API 的服务与数据结构,支持流量查询、用户信息获取、用户列表和配置管理等功能。


配置 CMake 构建系统

接下来在 CMakeLists.txt 文件中配置 CMake,以便编译和链接所需的库和依赖。

cmake_minimum_required(VERSION 3.16)
project(trojan-go LANGUAGES CXX)set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Protobuf Grpc)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Protobuf Grpc)add_executable(client main.cpp)qt_add_protobuf(clientPROTO_FILESapi.proto
)qt_add_grpc(client CLIENTPROTO_FILESapi.proto
)include(GNUInstallDirs)
install(TARGETS clientLIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
CMake 配置解析
  • qt_add_protobufqt_add_grpc 用于生成 Protobuf 和 gRPC 的 C++ 代码。
  • install 指定安装路径,将可执行文件安装到系统的标准目录。

实现 Trojan-Go 客户端

main.cpp 文件实现了客户端的主要逻辑,负责与服务器通信并处理流量信息。

main.cpp 内容
#include <QCoreApplication>
#include <QTimer>
#include <memory>
#include "api.qpb.h"
#include "api_client.grpc.qpb.h"
#include <QGrpcHttp2Channel>
#include <QGrpcChannelOptions>
#include <QGrpcStatus>
#include <QGrpcCallReply>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);trojan::api::TrojanClientService::Client client;QGrpcChannelOptions channelOptions;QUrl clientApi = QUrl("http://127.0.0.128:10000"/*用户设定的 trojan-go api 地址和端口*/, QUrl::StrictMode);std::shared_ptr<QGrpcHttp2Channel> channel = std::make_shared<QGrpcHttp2Channel>(clientApi, channelOptions);if(client.attachChannel(channel)) {qDebug() << "attachChannel success";} else {qDebug() << "attachChannel failed";};QTimer timer;QObject::connect(&timer, &QTimer::timeout, &a, [&]() {trojan::api::User user;user.setPassword("trojan-go.com"/*用户连接服务器的密码*/);trojan::api::GetTrafficRequest req;req.setUser(user);std::unique_ptr<QGrpcCallReply> reply = client.GetTraffic(req);auto *replyPtr = reply.get();QObject::connect(replyPtr,&QGrpcCallReply::finished,&a,[reply = std::move(reply)](const QGrpcStatus &status) {if(!status.isOk()) {qDebug() << "Failed to send message: " << status;} else {trojan::api::GetTrafficResponse response;if(reply->read(&response)) {qDebug() << "Success:" << response.success();qDebug() << "Info:" << response.info();double downloadTrafficMB = response.trafficTotal().downloadTraffic() / 1024.0 / 1024.0;double uploadTrafficMB   = response.trafficTotal().uploadTraffic() / 1024.0 / 1024.0;double downloadSpeedMBps = response.speedCurrent().downloadSpeed() / 1024.0 / 1024.0;double uploadSpeedMBps   = response.speedCurrent().uploadSpeed() / 1024.0 / 1024.0;qDebug() << QString("Download Traffic: %1 MB").arg(downloadTrafficMB, 0, 'f', 2);qDebug() << QString("Upload Traffic: %1 MB").arg(uploadTrafficMB, 0, 'f', 2);qDebug() << QString("Download Speed: %1 MB/s").arg(downloadSpeedMBps, 0, 'f', 2);qDebug() << QString("Upload Speed: %1 MB/s").arg(uploadSpeedMBps, 0, 'f', 2);qDebug() << "";} else {qDebug() << "Failed to parse GetTrafficResponse.";}}},Qt::SingleShotConnection);});timer.start(500);return a.exec();
}
代码详解
  • 连接服务器:使用 QGrpcHttp2Channel 通过 HTTP/2 连接到服务器。
  • 定时器监控:每 500 毫秒发送一次 GetTraffic 请求以获取最新流量和速度统计数据。
  • 结果解析和输出:解析服务器返回的流量数据并输出到控制台。
使用定时器实现数据流量和速度监控

通过 Qt 的 QTimer 实现客户端定时请求服务器流量和速度统计数据并进行处理。在实际应用中,定时更新数据可以实时监控服务器的状态,有助于及时获取连接信息并检测异常。


总结

本文介绍了如何使用 Qt 和 gRPC 实现一个高效的 Trojan-Go 客户端。从环境配置、Protobuf 文件定义、CMake 构建配置到主程序逻辑,我们全面讲解了客户端实现的每一步骤。借助 Qt 和 gRPC 的自动化工具,开发者能够更高效地实现客户端应用,同时享受 gRPC 高效的通信和 Qt 的跨平台支持。这一项目展示了 gRPC 的强大应用场景,也为开发更复杂的网络应用打下了基础。

相关文章:

使用 Qt GRPC 构建高效的 Trojan-Go 客户端:详细指南

使用 Qt GRPC 构建高效的 Trojan-Go 客户端&#xff1a;详细指南 初识 Qt 和 gRPC 什么是 Qt&#xff1f;什么是 gRPC&#xff1f; 项目结构概述创建 proto 文件定义 API 下载 api.proto 文件解析 proto 文件 1. package 与 option 语句2. 消息类型定义 TrafficSpeedUserUserSt…...

【mysql进阶】5-事务和锁

mysql 事务基础 1 什么是事务 事务是把⼀组SQL语句打包成为⼀个整体&#xff0c;在这组SQL的执⾏过程中&#xff0c;要么全部成功&#xff0c;要么全部失败&#xff0c;这组SQL语句可以是⼀条也可以是多条。再来看⼀下转账的例⼦&#xff0c;如图&#xff1a; 在这个例⼦中&a…...

指增和中性产品的申赎加减仓及资金调拨自动化伪代码思路

定义一些关键字代表的意义 STRUCT: 代表需要输入的格式化的信息IMPORT: 代表需要输入的外部信息&#xff0c; 这些信息通常是客观的SEARCH: 需要从某地比如数据库检索搜集信息SUM: 一种宏观的加和操作&#xff0c; 比如两个股票户ABAB&#xff0c;微观上实际还是有差异GROUP: …...

【论文分享】居住开放空间如何影响老年人的情感:使用可穿戴传感器的现场实验

本研究首次通过跟踪实时、高分辨率的环境暴露和情绪反应来研究和比较不同质量住宅社区中的居住开放空间&#xff08;ROS&#xff09;与老年人情绪之间关联&#xff1b;并采用混合方法&#xff0c;包括可穿戴传感器和问卷调查&#xff0c;收集了中国广州老年居民的客观和主观住宅…...

入门 | Prometheus+Grafana 普罗米修斯

#1024程序员节&#xff5c;征文# 一、prometheus介绍 1、监控系统组成 一个完整的监控系统需要包括如下功能&#xff1a;数据产生、数据采集、数据存储、数据处理、数据展示、分析、告警等。 &#xff08;1&#xff09;、数据来源 数据来源&#xff0c;也就是需要监控的数据…...

制作Ubuntu根文件系统

制作Ubuntu根文件系统&#xff1a; gunzip ubuntu-base-22.04.5-base-arm64.tar.gz mkdir ubuntu tar xvpf ubuntu-base-22.04.5-base-arm64.tar -C ubuntu 挂载目录、复制dns、执行chroot cd /userdisk/ubuntu cp /etc/resolv.conf ./etc/resolv.conf mount --bind /dev ./d…...

16个最佳测试管理工具(2024)

1、前言 测试管理解决方案能够帮助你捕捉测试需求、设计测试用例、生成测试执行报告、管理资源等。软件质量的疏忽可能导致公司遭受巨大的经济损失、声誉损害或面临诉讼风险。一个优秀的测试管理工具是防止缺陷和故障进入生产环节的关键。 2、PractiTest ​ 功能特点&#x…...

基于知识图谱的猕猴桃种植技术问答系统

猕猴桃怎么种植更高效、病虫害怎么防治、最适宜的气候条件有哪些&#xff1f;作为一名科技研发迷&#xff0c;这些问题是不是听起来很有挑战性&#xff1f;咱们今天就来聊聊一个特别的研发项目——基于知识图谱的猕猴桃种植技术问答系统。这不仅仅是一个农业项目&#xff0c;它…...

Swift雨燕蜂窝无线通信系统介绍

本文博客链接:jdh99-CSDN博客,作者:jdh,转载请注明. 1. 概述 物联网小无线通信技术众多&#xff0c;其中大多是小范围小规模的无线通信技术&#xff0c;而行业难点是如何做到广覆盖、大容量、低功耗。 针对以上难点&#xff0c;宏讯物联研发了Swift雨燕蜂窝无线通信技术&…...

【ZZULI】数据库第二次实验

【ZZULI】数据库第二次实验 创建学生信息管理系统的数据库通过T-SQL语句创建学生表、课程表、选课表创建学生表创建课程表创建选课表 修改表结构。为SC表添加写的列&#xff0c;列名为备注修改备注列的数据长度。删除SC表的备注列。 通过T-SQL语句对表的列添加约束&#xff0c;…...

Javaee---多线程(一)

文章目录 1.线程的概念2.休眠里面的异常处理3.实现runnable接口4.匿名内部类子类创建线程5.匿名内部类接口创建线程6.基于lambda表达式进行线程创建7.关于Thread的其他的使用方法7.1线程的名字7.2设置为前台线程7.3判断线程是否存活 8.创建线程方法总结9.start方法10.终止&…...

Java后端面试内容总结

先讲项目背景&#xff0c;再讲技术栈模块划分&#xff0c; 讲业务的时候可以先讲一般再特殊 为什么用这个&#xff0c;好处是什么&#xff0c;应用场景 Debug发现问题/日志发现问题. QPS TPS 项目单元测试&#xff0c;代码的变更覆盖率达到80%&#xff0c;项目的复用性高…...

DC-1渗透测试

DC1 五个flag的拿取&#xff08;截图是五个flag里面的内容&#xff09; 注意事项&#xff1a;kali的用户名&#xff1a;root 密码&#xff1a;kali 注意&#xff1a;DC1 只要开机服务就起来了 思路&#xff1a;信息收集—> 寻找漏洞—> 利用漏洞(sql注入,文件上传漏洞…...

深度剖析:电商 API 接口如何成就卓越用户体验

在电商领域的激烈竞争中&#xff0c;提供卓越的用户体验已成为企业脱颖而出的关键。而电商 API 接口在其中扮演着举足轻重的角色&#xff0c;它如同电商平台的神经系统&#xff0c;连接着各个关键环节&#xff0c;为用户带来无缝、高效且个性化的购物之旅。 一、极速响应&#…...

C++调试经验:Ubuntu下CMake链接常见库的方式(持续更新)

目录 1. CMake链接OpenCV库 2. CMake链接VTK库 3. CMake链接Qt库 4. CMake链接PCL库 5. CMake链接Gstreamer 6. CMake链接json-cpp库 7. CMake链接yaml-cpp库 8. CMake链接breakpad库 9. CMake链接Eigen3库 1. CMake链接OpenCV库 find_package (OpenCV 4 REQUIRED)…...

【HarmonyOS】应用实现APP国际化多语言切换

【HarmonyOS】应用实现APP国际化多语言切换 前言 在鸿蒙中应用国际化处理&#xff0c;与Android和IOS基本一致&#xff0c;都是通过JSON配置不同的语言文本内容。在UI展示时&#xff0c;使用JSON配置的字段key进行调用&#xff0c;系统选择对应语言文本内容。 跟随系统多语言…...

使用pandas进行数据分析

文章目录 1.pandas的特点2.Series2.1新建Seriws2.2使用标签来选择数据2.3 通过指定位置选择数据2.4 使用布尔值选择数据2.5 其他操作2.5.1 修改数据2.5.2 统计操作2.5.3 缺失数据处理 3.DataFrame3.1 新建 DataFrame3.2 选择数据3.2.1 使用标签选择数据3.2.2 使用 iloc 选择数据…...

用于无监督域适应的提示分布对齐

论文探讨了视觉语言模型&#xff08;VLMs&#xff09;及其在无监督域适应&#xff08;UDA&#xff09;中的应用&#xff0c;并引入了一种名为提示分布对齐&#xff08;Prompt-based Distribution Alignment&#xff0c;PDA&#xff09;的方法&#xff0c;该方法采用双分支训练策…...

Rust整合Elasticsearch

Elasticsearch是什么 Lucene&#xff1a;Java实现的搜索引擎类库 易扩展高性能仅限Java开发不支持水平扩展 Elasticsearch&#xff1a;基于Lucene开发的分布式搜索和分析引擎 支持分布式、水平扩展提高RestfulAPI&#xff0c;可被任何语言调用 Elastic Stack是什么 ELK&a…...

Linux 文件权限管理:chown、chgrp 和 chmod 的使用及权限掩码规则

目录 文件权限的基本概念 chown&#xff1a;更改文件的拥有者 使用方法 示例 选项 chgrp&#xff1a;更改文件的所属组 使用方法 示例 chmod&#xff1a;更改文件的权限 使用方法 权限表示 选项 权限掩码&#xff08;umask&#xff09;规则 如何查看和设置 umask…...

简单记录ios打包流程

1、点击这里获取UDID 2、xcode登录开发者账户、确定唯一id&#xff08;Bundle ID&#xff09; 3、去这里注册appid 4、在这里这里创建app 5、之后xcode中打包...

右键以vscode打开目录的时候出现找不到应用程序

出现这个问题的主要原因&#xff0c;大概率可能是因为你移动了vscode的安装路径导致的。 解决办法 打开注册表&#xff1a;通过cmd 打开regedit 然后搜索&#xff1a;计算机\HKEY_CLASSES_ROOT\Directory\Background\shell 这个两个参数可以自己比对一下&#xff0c;主要需要检…...

【Go-Taskflow:一个类似任务流的有向无环图(DAG)任务执行框架,集成了可视化和性能分析工具,旨在简化并行任务的复杂依赖管理】

Go-Taskflow是一个静态有向无环图&#xff08;DAG&#xff09;任务计算框架&#xff0c;它受到taskflow-cpp的启发&#xff0c;结合了Go语言的原生能力和简洁性&#xff0c;特别适合于并发任务中复杂的依赖管理。 Go-Taskflow的主要特点包括&#xff1a; 高可扩展性&#xff1…...

排查PHP服务器CPU占用率高的问题

排查PHP服务器CPU占用率高的问题通常可以通过以下步骤进行&#xff1a; 使用top或htop命令&#xff1a;这些命令可以实时显示服务器上各个进程的CPU和内存使用情况。找到CPU使用率高的进程。 查看进程日志&#xff1a;如果PHP-FPM或Apache等服务器进程的日志记录了具体的请求…...

【学术会议论文投稿】“从零到一:使用IntelliJ IDEA打造你的梦幻HTML项目“

【JPCS独立出版】2024年工业机器人与先进制造技术国际学术会议&#xff08;IRAMT 2024&#xff09;_艾思科蓝_学术一站式服务平台 更多学术会议请看 学术会议-学术交流征稿-学术会议在线-艾思科蓝 目录 引言&#xff1a;为何选择IntelliJ IDEA&#xff1f; 第一步&#xff1a…...

Win11安装基于WSL2的Ubuntu

1. 概述 趁着还没有完全忘记&#xff0c;详细记录一下在Win11下安装基于WSL2的Ubuntu的详细过程。不得不说WSL2现在被微软开发的比较强大了&#xff0c;还是很值得安装和使用的&#xff0c;笔者就通过WSL2安装的Ubuntu成功搭建了ROS环境。 2. 详论 2.1 子系统安装 在Win11搜…...

如何对pdf文件进行加密?pdf文件加密全攻略与深度解析(5个方法)

如何对pdf文件进行加密&#xff1f; 只见&#xff0c;在深夜的情报局里&#xff0c;特工小李将一份绝密PDF文件放在保险箱内&#xff0c;以为这样就天衣无缝了。 细细推敲&#xff0c;漏洞百出&#xff1a; 如果钥匙被盗呢&#xff1f;如果被神匠破解出密码呢&#xff1f;如果…...

c++面向对象三大特性之一-----多态

前言:本文将介绍在32位平台下,c的多态,通过本篇文章的学习你讲了解多态的原理,多态的底层还有一些不常见的关键字的介绍(final,override). 文章内容如下&#xff1a; 1:多态的概念 2:多态的定义与实现 3:多态的原理 4:抽象类 文章正式开始 1&#xff1a;多态的概念 多…...

8.Linux按键驱动-中断下半部

1.编程思路 1.1在gpio结构体中添加tasklet_struct结构体 1.2在probe函数中初始化tasklet结构体 1.3在中断服务程序中调度tasklet 1.4在这个函数中执行其它任务 2.代码&#xff1a; 应用程序和Makefile和上节一致 https://blog.csdn.net/weixin_40933496/article/details/1…...

Redis 线程控制 总结

前言 相关系列 《Redis & 目录》&#xff08;持续更新&#xff09;《Redis & 线程控制 & 源码》&#xff08;学习过程/多有漏误/仅作参考/不再更新&#xff09;《Redis & 线程控制 & 总结》&#xff08;学习总结/最新最准/持续更新&#xff09;《Redis &a…...