使用 Qt GRPC 构建高效的 Trojan-Go 客户端:详细指南
- 使用 Qt GRPC 构建高效的 Trojan-Go 客户端:详细指南
- 初识 Qt 和 gRPC
- 什么是 Qt?
- 什么是 gRPC?
- 项目结构概述
- 创建 proto 文件定义 API
- 下载
api.proto文件 - 解析 proto 文件
- 1.
package与option语句 - 2. 消息类型定义
TrafficSpeedUserUserStatusGetTrafficRequest和GetTrafficResponseListUsersRequest和ListUsersResponseGetUsersRequest和GetUsersResponseSetUsersRequest和SetUsersResponse
- 3. 服务定义
TrojanClientServiceTrojanServerService
- 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…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
