Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

QProtocolUnit

QProtocolUnit 是一个基于 Qt 的网络通信组件,封装了 TCP 客户端、TCP 服务端、UDP 通信、HTTP 请求和可中断线程模型。项目可用于 Qt 工程中的通信模块集成,也提供 Qt Widgets 示例界面用于调试 TCP/UDP 数据收发。

日志模块 QCuteLogger 基于 GitHub 上的开源项目 CuteLogger 集成和适配。

功能特性

  • TCP 服务端:基于 QTcpServer,每个客户端连接由独立线程管理。
  • TCP 客户端:支持连接、断开、重连、连接状态通知和数据收发。
  • UDP 通信:支持单播、广播、组播,并支持指定网卡。
  • HTTP 请求:封装 GET、POST、Header、Cookie 等常用操作。
  • 可中断线程:提供线程启动、暂停、恢复、退出和事件循环支持。
  • 日志模块:集成 QCuteLogger,用于控制台、文件和滚动日志输出。

项目结构

.
├── CommonBase.pri
├── QProtocolUnit/
│ ├── inc/ # 通信组件头文件
│ ├── src/ # 通信组件实现与示例入口
│ ├── ui/ # TCP/UDP 示例界面
│ ├── QProtocolUnit.pro # 示例程序工程
│ ├── QProtocolUnit_inc.pri # 头文件引用配置
│ └── QProtocolUnit_src.pri # 源文件引用配置
└── QCuteLogger/
├── inc/ # 日志模块头文件
├── src/ # 日志模块实现
└── QCuteLogger.pro # 日志库工程

环境要求

  • Qt 5 或 Qt 6
  • qmake
  • C++11
  • Qt 模块:
    • core
    • gui
    • widgets
    • network
    • sql
    • concurrent

Qt 6 下 QCuteLogger 会额外使用:

core5compat

构建

当前 QProtocolUnit.pro 默认配置为示例程序:

TEMPLATE = appTARGET = QProtocolUnit

建议先构建日志库,再构建示例程序。

使用 Qt Creator

  1. 打开 QCuteLogger/QCuteLogger.pro 并构建。
  2. 打开 QProtocolUnit/QProtocolUnit.pro 并构建运行。

使用命令行

cd QCuteLogger
qmake QCuteLogger.pro
make
cd ../QProtocolUnit
qmake QProtocolUnit.pro
make

Windows 下根据编译器使用对应命令:

mingw32-make

或:

nmake

构建输出目录由 CommonBase.pri 控制:

  • MSVC:bin-msvc
  • MinGW:bin-mingw
  • Debug 目标默认追加 d 后缀,例如 QProtocolUnitdQCuteLoggerd

集成到其他 Qt 工程

源码方式集成

在业务工程 .pro 中引入源码配置:

QT += coregui widgets networksql concurrent
CONFIG += c++11
include(path/to/QProtocolUnit/QProtocolUnit/QProtocolUnit_src.pri)
include(path/to/QProtocolUnit/QCuteLogger/QCuteLogger_src.pri)

如果业务工程不需要示例界面,可以只引入核心通信类对应的 .h/.cpp 文件:

  • interruptthread
  • clientthread
  • clientsocket
  • serversocket
  • udpthread
  • udpsocket
  • httpclient

库方式集成

如果已将模块构建为库,可在业务工程中加入:

INCLUDEPATH += path/to/QProtocolUnit/QProtocolUnit/incINCLUDEPATH += path/to/QProtocolUnit/QCuteLogger/incLIBS += -Lpath/to/bin-lQProtocolUnitLIBS += -Lpath/to/bin-lQCuteLogger

Debug 版本按当前命名规则使用:

LIBS += -lQProtocolUnitdLIBS += -lQCuteLoggerd

快速开始

TCP 服务端

#include"serversocket.h"
ServerSocket server;
server.startServer(5130);
connect(&server, &ServerSocket::sig_newClient,
[](QString host, int port) {
qDebug() << "new client:" << host << port;
});
connect(&server, &ServerSocket::sig_newMsg,
[](QString host, int port, QByteArray data) {
qDebug() << "recv:" << host << port << data;
});
server.writeToClient("hello", "127.0.0.1", 50000);

TCP 客户端

#include"clientthread.h"
ClientThread *client = new ClientThread(socket_client);
client->setClient(nullptr, "127.0.0.1", 5130);
connect(client, &ClientThread::sig_receiveData,
[](QString host, int port, QByteArray data) {
qDebug() << "recv from server:" << host << port << data;
});
connect(client, &ClientThread::sig_stateChanged,
[](QString host, int port, int state) {
qDebug() << "state:" << host << port << state;
});
client->createThread();
client->startThread();
client->appendDataToClient("hello server");

UDP 单播

#include"udpthread.h"
UDPThread *udp = new UDPThread;
udp->setClient(
nullptr,
"192.168.0.100", // 目标地址8880, // 目标端口8881// 本地端口
);
connect(udp, &UDPThread::sig_receiveData,
[](QString host, QByteArray data) {
qDebug() << "udp recv:" << host << data;
});
udp->createThread();
udp->startThread();
udp->appendDataToClient("hello udp");

UDP 组播

udp->setClient(
nullptr,
"239.255.0.1",
8888,
8888,
broad_group
);

如需指定网卡,可传入 QNetworkInterface

QNetworkInterface net = QNetworkInterface::interfaceFromName("eth0");
udp->setClient(
nullptr,
"239.255.0.1",
8888,
8888,
broad_group,
net
);

HTTP 请求

#include"httpclient.h"
QMap<QString, QString> headers;
headers.insert("User-Agent", "QProtocolUnit");
QByteArray data = getClientHandler()->get("https://example.com", headers);
qDebug() << data;

POST 示例:

QByteArray body = R"({"name":"test"})";
QByteArray reply = getClientHandler()->postData("https://example.com/api", body);

核心类说明

说明
InterruptThread可中断线程基类,提供启动、暂停、恢复、退出能力
ClientThreadTCP 连接线程,负责单个 TCP 连接的数据收发
ClientSocketTCP Socket 封装,通常由 ClientThread 内部使用
ServerSocketTCP 服务端,负责监听、接入控制和客户端线程管理
UDPThreadUDP 通信线程
UDPSocketUDP Socket 封装,支持单播、广播、组播
HttpClientHTTP 请求封装
HttpClientHandlerHTTP 请求便捷调用封装
ClientTableViewModel示例界面中使用的客户端列表模型

使用注意事项

线程启动顺序

ClientThreadUDPThread 推荐按以下顺序使用:

setClient(...);
createThread();
startThread();

TCP 连接生命周期

  • closeClient():关闭当前连接,但保留连接线程。
  • openClient():重新打开已关闭的连接。
  • deleteClient():删除连接并结束线程。
  • appendDataToClient():向发送队列追加数据,适合跨线程发送。

服务端连接管理

ServerSocket 支持按 IP 或 IP + Port 管理客户端连接:

server.stopClient("127.0.0.1");
server.stopClient("127.0.0.1", 50000);
server.delClient("127.0.0.1");
server.delClient("127.0.0.1", 50000);

服务端也支持黑白名单:

server.addClientToBlackList("192.168.1.10");
server.removeClientFromBlackList("192.168.1.10");
server.addClientToWhiteList("192.168.1.20");
server.removeClientFromWhiteList("192.168.1.20");

线程安全

  • ClientSocket 应在线程内部使用,不建议在主线程直接调用。
  • ServerSocket 的管理接口建议在主线程调用。
  • 跨线程发送数据时,优先使用信号槽或 appendDataToClient()

UDP 注意事项

UDP 是无连接协议,发送成功只表示数据已交给系统发送,不代表对端一定收到。组播模式下需要确认本机网卡、组播地址和端口配置正确。

示例程序

QProtocolUnit 示例程序启动两个界面:

  • ProtocolForm:TCP 服务端/客户端调试界面。
  • UDPForm:UDP 单播、组播调试界面。

示例程序可用于验证本地端口监听、客户端连接、数据收发、连接状态变化和组播网卡选择。

第三方组件

本项目包含并适配了以下第三方开源组件:

组件来源说明
QCuteLogger / CuteLoggerdept2/CuteLoggerQt 日志组件,本项目中用于日志输出,并做了工程结构和 Qt 版本适配

如需了解 CuteLogger 的原始实现和授权信息,请参考其上游仓库。

许可证

本项目使用 MIT License 发布。详情见 LICENSE

项目中集成的第三方组件仍遵循其原始许可证要求。

About

A Qt-based network communication module for TCP client/server, UDP unicast/broadcast/multicast, HTTP requests, and interruptible thread handling.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages