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

 
 
使用 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. package 与 option 语句
 
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 数量。
GetTrafficRequest 和 GetTrafficResponse
 
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,以及流量数据和速度数据。
ListUsersRequest 和 ListUsersResponse
 
message ListUsersRequest {}message ListUsersResponse {UserStatus status = 1;
}
- ListUsersRequest不含字段,用于请求用户列表。
- ListUsersResponse返回每个用户的状态信息。
GetUsersRequest 和 GetUsersResponse
 
message GetUsersRequest {User user = 1;
}message GetUsersResponse {bool success = 1;string info = 2;UserStatus status = 3;
}
- GetUsersRequest请求特定用户的信息。
- GetUsersResponse返回状态- success、信息- info和用户状态- UserStatus。
SetUsersRequest 和 SetUsersResponse
 
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包含- UserStatus和- Operation,用于增加、删除或修改用户。
- SetUsersResponse返回操作状态- success和相关信息- info。
3. 服务定义
TrojanClientService
 
service TrojanClientService {rpc GetTraffic(GetTrafficRequest) returns(GetTrafficResponse){}
}
- 定义 GetTrafficRPC 方法,允许客户端请求其流量信息。
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_protobuf和- qt_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 客户端:详细指南 初识 Qt 和 gRPC 什么是 Qt?什么是 gRPC? 项目结构概述创建 proto 文件定义 API 下载 api.proto 文件解析 proto 文件 1. package 与 option 语句2. 消息类型定义 TrafficSpeedUserUserSt…...
 
【mysql进阶】5-事务和锁
mysql 事务基础 1 什么是事务 事务是把⼀组SQL语句打包成为⼀个整体,在这组SQL的执⾏过程中,要么全部成功,要么全部失败,这组SQL语句可以是⼀条也可以是多条。再来看⼀下转账的例⼦,如图: 在这个例⼦中&a…...
 
指增和中性产品的申赎加减仓及资金调拨自动化伪代码思路
定义一些关键字代表的意义 STRUCT: 代表需要输入的格式化的信息IMPORT: 代表需要输入的外部信息, 这些信息通常是客观的SEARCH: 需要从某地比如数据库检索搜集信息SUM: 一种宏观的加和操作, 比如两个股票户ABAB,微观上实际还是有差异GROUP: …...
 
【论文分享】居住开放空间如何影响老年人的情感:使用可穿戴传感器的现场实验
本研究首次通过跟踪实时、高分辨率的环境暴露和情绪反应来研究和比较不同质量住宅社区中的居住开放空间(ROS)与老年人情绪之间关联;并采用混合方法,包括可穿戴传感器和问卷调查,收集了中国广州老年居民的客观和主观住宅…...
 
入门 | Prometheus+Grafana 普罗米修斯
#1024程序员节|征文# 一、prometheus介绍 1、监控系统组成 一个完整的监控系统需要包括如下功能:数据产生、数据采集、数据存储、数据处理、数据展示、分析、告警等。 (1)、数据来源 数据来源,也就是需要监控的数据…...
制作Ubuntu根文件系统
制作Ubuntu根文件系统: 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…...
 
基于知识图谱的猕猴桃种植技术问答系统
猕猴桃怎么种植更高效、病虫害怎么防治、最适宜的气候条件有哪些?作为一名科技研发迷,这些问题是不是听起来很有挑战性?咱们今天就来聊聊一个特别的研发项目——基于知识图谱的猕猴桃种植技术问答系统。这不仅仅是一个农业项目,它…...
 
Swift雨燕蜂窝无线通信系统介绍
本文博客链接:jdh99-CSDN博客,作者:jdh,转载请注明. 1. 概述 物联网小无线通信技术众多,其中大多是小范围小规模的无线通信技术,而行业难点是如何做到广覆盖、大容量、低功耗。 针对以上难点,宏讯物联研发了Swift雨燕蜂窝无线通信技术&…...
 
【ZZULI】数据库第二次实验
【ZZULI】数据库第二次实验 创建学生信息管理系统的数据库通过T-SQL语句创建学生表、课程表、选课表创建学生表创建课程表创建选课表 修改表结构。为SC表添加写的列,列名为备注修改备注列的数据长度。删除SC表的备注列。 通过T-SQL语句对表的列添加约束,…...
 
Javaee---多线程(一)
文章目录 1.线程的概念2.休眠里面的异常处理3.实现runnable接口4.匿名内部类子类创建线程5.匿名内部类接口创建线程6.基于lambda表达式进行线程创建7.关于Thread的其他的使用方法7.1线程的名字7.2设置为前台线程7.3判断线程是否存活 8.创建线程方法总结9.start方法10.终止&…...
 
Java后端面试内容总结
先讲项目背景,再讲技术栈模块划分, 讲业务的时候可以先讲一般再特殊 为什么用这个,好处是什么,应用场景 Debug发现问题/日志发现问题. QPS TPS 项目单元测试,代码的变更覆盖率达到80%,项目的复用性高…...
 
DC-1渗透测试
DC1 五个flag的拿取(截图是五个flag里面的内容) 注意事项:kali的用户名:root 密码:kali 注意:DC1 只要开机服务就起来了 思路:信息收集—> 寻找漏洞—> 利用漏洞(sql注入,文件上传漏洞…...
深度剖析:电商 API 接口如何成就卓越用户体验
在电商领域的激烈竞争中,提供卓越的用户体验已成为企业脱颖而出的关键。而电商 API 接口在其中扮演着举足轻重的角色,它如同电商平台的神经系统,连接着各个关键环节,为用户带来无缝、高效且个性化的购物之旅。 一、极速响应&#…...
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国际化多语言切换 前言 在鸿蒙中应用国际化处理,与Android和IOS基本一致,都是通过JSON配置不同的语言文本内容。在UI展示时,使用JSON配置的字段key进行调用,系统选择对应语言文本内容。 跟随系统多语言…...
使用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 选择数据…...
 
用于无监督域适应的提示分布对齐
论文探讨了视觉语言模型(VLMs)及其在无监督域适应(UDA)中的应用,并引入了一种名为提示分布对齐(Prompt-based Distribution Alignment,PDA)的方法,该方法采用双分支训练策…...
 
Rust整合Elasticsearch
Elasticsearch是什么 Lucene:Java实现的搜索引擎类库 易扩展高性能仅限Java开发不支持水平扩展 Elasticsearch:基于Lucene开发的分布式搜索和分析引擎 支持分布式、水平扩展提高RestfulAPI,可被任何语言调用 Elastic Stack是什么 ELK&a…...
 
Linux 文件权限管理:chown、chgrp 和 chmod 的使用及权限掩码规则
目录 文件权限的基本概念 chown:更改文件的拥有者 使用方法 示例 选项 chgrp:更改文件的所属组 使用方法 示例 chmod:更改文件的权限 使用方法 权限表示 选项 权限掩码(umask)规则 如何查看和设置 umask…...
 
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
 
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
 
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
 
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
 
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
 
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
