C++ QT项目推荐-仿微信聊天,支持Linux C++后端
本项目基于Qt6和Linux C++实现了一个即时聊天系统,包含客户端和服务端。服务端采用多线程架构,使用SQLite存储数据,实现用户注册、好友管理、群组聊天等功能。客户端通过Qt6开发,支持一对一和群聊。项目采用自定义协议(长度前缀+JSON)进行通信,具有跨平台特性。当前版本支持基础聊天功能,但在高并发、离线消息和安全性方面存在局限。建议后续引入线程池、消息队列和SSL加密等优化措施。该项目
1 项目简介
采用QT6制作客户端,Linux C++实现后端。为用户提供了一个即时聊天平台。
项目地址:https://gitee.com/voice-of-sentiment/chat-forge.git
视频讲解与源码领取:C++ QT项目推荐-仿微信聊天实现添加好友,一对一和群聊,支持Linux C++后端

2 Linux C++后端编译和运行
开源项目地址
git clone https://gitee.com/voice-of-sentiment/chat-forge.git
cd chat-forge/server/thirdparty
git clone https://gitee.com/NEU-lab/SQLiteCpp.git
# 如果用老廖提供的源码,直接解压源码包就行
#回到chat-forge/server目录
cd ..
cd build
rm -rf *
#重新cmake 编译debug方式
cmake -DCMAKE_BUILD_TYPE=Debug ..
make -j4
编译成功后产生server执行文件。
运行:
./server
默认监听端口为:8888
3 QT客户端编译和运行
编译环境:QT6.5 MinGW 64-bit
运行代码前修改服务器地址的ip和端口。

注册账号要用数字:

再开启一个客户端
用法很简单:在 Qt 提供的命令行里对 exe 运行 windeployqt,把需要的 Qt 插件/DLL 拷到同目录即可。
步骤
-
打开“Qt 6.5.0 for Desktop (MinGW 64-bit)”命令提示符(保证 windeployqt 在 PATH 中)。
-
进入你的 exe 目录:
# 先切换盘符
F:
# 进入到具体路径
cd F:\0voice\vip\tc\202412\build-OurChat-Desktop_Qt_6_5_0_MinGW_64_bit-Debug\debug
-
执行部署(Debug 构建):
windeployqt --verbose 2 --no-translations OurChat.exe
-
如果是 Release 构建,进入 release 目录,执行:
windeployqt --release --verbose 2 --no-translations OurChat.exe
-
执行后,exe 目录应出现 platforms\qwindows.dll、styles\...、imageformats\... 等子目录及多个 Qt6*.dll。
-
双击 OurChat.exe 启动;若提示缺少 DLL,多半是 MinGW 运行库未拷贝或混用了 Debug/Release 库。
4 Linux后端架构详解
4.1 服务端整体架构
服务端采用多线程 + 会话管理 + 命令分发的架构模式,为每个客户端连接分配独立的处理线程。
核心组件说明
|
组件 |
功能 |
实现文件 |
|---|---|---|
|
main函数 |
服务器入口,监听端口,接受连接 |
main.cpp |
|
Session类 |
会话管理,消息收发,状态维护 |
session.h/cpp |
|
CommandHandler类 |
命令处理器,业务逻辑实现 |
CommandHandler.h/cpp |
|
SQLite数据库 |
数据持久化存储 |
user.db |
|
userMap |
在线用户映射表 |
map<int,int> |
线程模型
服务端采用一连接一线程模型:
-
主线程负责监听和接受连接
-
每个客户端连接分配独立的工作线程
-
线程间通过互斥锁保护共享资源
架构流程图

4.2 网络通信协议
消息格式设计
采用长度前缀 + JSON消息体的二进制协议:
[0-3字节] [4字节开始]
消息长度 JSON消息体
(4字节) (变长)
协议实现细节
发送消息流程:
-
将JSON对象序列化为字符串
-
计算消息长度(字节数)
-
构造4字节长度头 + JSON消息体
-
通过socket发送完整数据包
接收消息流程:
-
先读取4字节获取消息长度
-
根据长度读取完整JSON数据
-
解析JSON并分发到对应处理函数
// 发送示例代码
void Session::sendMsg(json &j) {
std::string msg = j.dump();
int len = msg.length();
char buffer[4];
memcpy(buffer, &len, sizeof(len));
char *message = new char[4 + len];
memcpy(message, buffer, 4); // 长度头
memcpy(message + 4, msg.c_str(), len); // JSON体
send(m_socket, message, len + 4, 0);
}
4.3 数据库设计
数据表详细说明
|
表名 |
用途 |
主要字段 |
|---|---|---|
|
user |
用户基本信息 |
account(账号), password(密码), name(昵称), signature(签名), online(在线状态), icon(头像) |
|
friend |
好友关系 |
user1, user2 (双向好友关系) |
|
group_table |
群组信息 |
group_account(群号), group_name(群名), create_time(创建时间), group_master(群主) |
|
member |
群成员关系 |
member_id(成员账号), group_account(群号), group_nickname(群昵称) |
数据库ER关系图

关键设计特点
-
用户账号自增:account字段自动递增,确保唯一性
-
双向好友关系:friend表通过(user1,user2)复合主键存储好友关系
-
群组层级管理:群主通过group_master字段关联到user表
-
群昵称支持:成员在不同群组可以有不同昵称
4.4 命令系统详解
命令枚举定义
enum commands {
cmd_regist = 0, // 用户注册
cmd_login, // 用户登录
cmd_logout, // 用户登出
cmd_friend_search, // 搜索好友
cmd_add_friend_request, // 添加好友请求
cmd_add_friend_response, // 添加好友响应
cmd_friend_list, // 获取好友列表
cmd_friend_chat, // 好友聊天
cmd_group_create, // 创建群组
cmd_group_search, // 搜索群组
cmd_group_join_request, // 加入群组请求
cmd_group_join_response, // 加入群组响应
cmd_group_list, // 获取群组列表
cmd_group_chat, // 群组聊天
cmd_group_member_list, // 获取群成员列表
cmd_group_member_add, // 添加群成员
cmd_group_member_del, // 删除群成员
cmd_set_icon // 设置头像
};
命令处理流程图

4.5 核心命令详解
用户认证类命令
1. 用户注册 (cmd_regist = 0)
客户端请求:
{
"cmd": 0,
"account": 12345,
"password": "123456",
"name": "张三"
}
服务端响应:
{
"cmd": 0,
"res": "yes", // 或 "no"
"err": "账号已存在" // 失败时的错误信息
}
处理逻辑:
-
检查账号是否已存在
-
插入用户记录到user表
-
自动添加系统好友(10000)
-
返回注册结果
2. 用户登录 (cmd_login = 1)
客户端请求:
{
"cmd": 1,
"account": 12345,
"password": "123456"
}
服务端响应:
{
"cmd": 1,
"res": "yes",
"info": ["张三", "hello", ":/Icons/src/QQIcon/icon.jpg"]
}
处理逻辑:
-
验证账号密码
-
更新在线状态为1
-
将连接加入userMap
-
返回用户基本信息
好友管理类命令
3. 搜索好友 (cmd_friend_search = 3)
客户端请求:
{
"cmd": 3,
"info": "12345" // 搜索的账号或昵称
}
服务端响应:
{
"cmd": 3,
"count": 1,
"msglist": [
{
"account": 12345,
"name": "张三",
"signature": "hello",
"online": 1,
"icon": ":/Icons/src/QQIcon/icon.jpg"
}
]
}
4. 获取好友列表 (cmd_friend_list = 6)
客户端请求:
{
"cmd": 6,
"account": 12345
}
服务端响应:
{
"cmd": 6,
"count": 2,
"msglist": [
{
"account": 10000,
"name": "系统消息",
"signature": "系统官方账号",
"online": 1,
"icon": ":/Icons/src/QQIcon/icon.jpg"
},
{
"account": 54321,
"name": "李四",
"signature": "在线状态",
"online": 0,
"icon": ":/Icons/src/QQIcon/icon.jpg"
}
]
}
5. 好友聊天 (cmd_friend_chat = 7)
客户端请求:
{
"cmd": 7,
"account": 12345, // 发送者账号
"friendAccount": 54321, // 接收者账号
"sendmsg": "你好!" // 消息内容
}
服务端处理:
-
转发消息给在线的目标好友
-
如果好友离线,消息暂不存储
群组管理类命令
6. 搜索群组 (cmd_group_search = 9)
客户端请求:
{
"cmd": 9,
"info": "群名称或群号"
}
服务端响应:
{
"cmd": 9,
"count": 1,
"msglist": [
{
"group_account": 100001,
"group_name": "技术交流群",
"group_master": 12345
}
]
}
7. 获取群组列表 (cmd_group_list = 12)
客户端请求:
{
"cmd": 12,
"account": 12345
}
服务端响应:
{
"cmd": 12,
"count": 1,
"msglist": [
{
"group_account": 100001,
"group_name": "技术交流群"
}
]
}
8. 群组聊天 (cmd_group_chat = 13)
客户端请求:
{
"cmd": 13,
"account": 12345,
"groupAccount": 100001,
"sendmsg": "大家好!"
}
服务端处理:
-
获取群组所有在线成员
-
广播消息给所有在线群成员
-
排除发送者本人
4.6 GDB网络调试详解
网络框架调试流程图

关键断点设置策略
为什么在这些位置打断点?
|
断点位置 |
调试目的 |
观察要点 |
|---|---|---|
|
main函数 |
服务器启动流程 |
端口绑定、数据库初始化 |
|
accept |
连接建立过程 |
客户端IP、连接数量 |
|
recv |
数据接收分析 |
消息格式、协议解析 |
|
send |
响应发送验证 |
响应内容、发送状态 |
详细调试步骤
1. main函数调试 - 服务器启动
设置断点:
(gdb) b main
Note: breakpoint 1 also set at pc 0x5555555782a2.
Breakpoint 4 at 0x5555555782a2: file /home/lqf/linux/reactor/chat-forge/server/main.cpp, line 13.
调试要点:
-
检查数据库初始化:SQLite::Database db("user.db")
-
验证表创建:CREATE TABLE IF NOT EXISTS user...
-
确认端口设置:default_port = 8888
-
观察socket创建:listen_fd = socket(AF_INET, SOCK_STREAM, 0)
关键变量监控:
(gdb) p default_port # 监控端口号
(gdb) p listen_fd # 监控socket文件描述符
(gdb) info locals # 查看所有局部变量
2. accept调试 - 连接监听
设置断点:
(gdb) b accept
# 或者更精确地在main.cpp的accept调用处
(gdb) b main.cpp:88
调用栈分析:
#0 __libc_accept (fd=4, addr=..., len=0x7fffffffde78) at ../sysdeps/unix/sysv/linux/accept.c:24
#1 0x00005555555784f1 in main (argc=1, argv=0x7fffffffdfe8) at /home/lqf/linux/reactor/chat-forge/server/main.cpp:88
调试要点:
-
服务器进入监听状态,等待客户端连接
-
观察客户端连接信息:IP地址和端口
-
监控新连接的socket文件描述符
-
验证线程创建和userMap更新
关键变量监控:
(gdb) p client_addr.sin_addr # 客户端IP
(gdb) p ntohs(client_addr.sin_port) # 客户端端口
(gdb) p connect_fd # 新连接的socket fd
(gdb) p userMap # 在线用户映射表
3. recv调试 - 数据接收
设置断点:
(gdb) b Session::recvMsg
# 或者在具体的recv系统调用处
(gdb) b session.cpp:301
调用栈分析:
#0 __libc_recv (fd=6, buf=0x7ffff71a0be4, len=4, flags=0) at ../sysdeps/unix/sysv/linux/recv.c:24
#1 in Session::recvMsg[abi:cxx11]() (this=) at /home/lqf/linux/reactor/chat-forge/server/session.cpp:301
#2 in taskThread (clientFd=6) at /home/lqf/linux/reactor/chat-forge/server/chatTask.cpp:13
#3 in std::__invoke_impl<void, void (*)(int), int> (__f=@0x55555570cd80: <taskThread(int)>) at /usr/include/c++/10/bits/invoke.h:60
#4 in std::__invoke<void (*)(int), int> (__fn=@0x55555570cd80: 0x55555557455f <taskThread(int)>) at /usr/include/c++/10/bits/invoke.h:95
#5 in std::thread::_Invoker<std::tuple<void (*)(int), int> >::_M_invoke<0ul, 1ul> (this=) at /usr/include/c++/10/thread:264
#6 in std::thread::_Invoker<std::tuple<void (*)(int), int> >::operator() (this=) at /usr/include/c++/10/thread:271
#7 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(int), int> > >::_M_run (this=) at /usr/include/c++/10/thread:215
#8 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#9 in start_thread (arg=<optimized out>) at pthread_create.c:477
#10 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
调试要点:
-
首先接收4字节长度头:recv(m_socket, buffer, 4, 0)
-
然后接收完整JSON数据:recv(m_socket, msg, len, MSG_WAITALL)
-
验证协议格式:长度前缀 + JSON消息体
-
观察JSON解析过程:json::parse(msg)
关键变量监控:
(gdb) p len # 消息长度
(gdb) x/4xb buffer # 查看4字节长度头的十六进制
(gdb) p msg # JSON字符串内容
(gdb) p j # 解析后的JSON对象
(gdb) p j["cmd"] # 命令类型
协议验证:
# 查看原始字节数据
(gdb) x/16xb buffer # 十六进制查看
(gdb) printf "%s\n", msg # 打印JSON字符串
4. send调试 - 响应发送
设置断点:
(gdb) b Session::sendMsg
# 或者在具体的send系统调用处
(gdb) b session.cpp:244
调用栈分析:
#0 __libc_send (fd=6, buf=0x7fffe8001180, len=78, flags=0) at ../sysdeps/unix/sysv/linux/send.c:24
#1 0x000055555557c66a in Session::sendMsg (this=, j=...) at /home/lqf/linux/reactor/chat-forge/server/session.cpp:244
#2 0x0000555555562e49 in CommandHandler::Login (account=110, password="1234", session=) at /home/lqf/linux/reactor/chat-forge/server/CommandHandler.cpp:65
#3 0x000055555557b088 in Session::handleMsg (this=, msg=...) at /home/lqf/linux/reactor/chat-forge/server/session.cpp:58
#4 0x000055555557ccb9 in Session::recvMsg[abi:cxx11]() (this=) at /home/lqf/linux/reactor/chat-forge/server/session.cpp:334
#5 0x00005555555745d6 in taskThread (clientFd=6) at /home/lqf/linux/reactor/chat-forge/server/chatTask.cpp:13
调试要点:
-
构造响应JSON:j.dump()
-
发送长度头:send(m_socket, message, 4, 0)
-
发送JSON数据:send(m_socket, message+4, len, 0)
-
验证发送状态和数据完整性
关键变量监控:
(gdb) p j # 响应JSON对象
(gdb) p msg # JSON字符串
(gdb) p len # 消息长度
(gdb) x/4xb buffer # 长度头的十六进制
(gdb) printf "%s\n", msg.c_str() # 响应内容
完整调试会话示例
# 启动GDB调试
$ gdb ./server
(gdb) b main
(gdb) b accept
(gdb) b Session::recvMsg
(gdb) b Session::sendMsg
(gdb) run
# 当客户端连接时
Breakpoint 2, accept (...)
(gdb) p client_addr.sin_addr
(gdb) c
# 当客户端发送消息时
Breakpoint 3, Session::recvMsg (...)
(gdb) p len
(gdb) p msg
(gdb) p j["cmd"]
(gdb) c
# 当服务器发送响应时
Breakpoint 4, Session::sendMsg (...)
(gdb) p j
(gdb) printf "%s\n", msg.c_str()
(gdb) c
调试最佳实践
常见问题排查
1.连接失败
-
检查端口是否被占用:netstat -tlnp | grep 8888
-
验证防火墙设置:iptables -L
-
确认服务器监听状态:ss -tlnp | grep 8888
2.消息解析错误
-
验证JSON格式:使用在线JSON验证工具
-
检查字符编码:确保UTF-8编码
-
监控消息长度:长度头与实际数据是否匹配
3.数据库操作失败
-
检查数据库文件权限:ls -la user.db
-
验证SQL语句:使用sqlite3命令行工具测试
-
监控数据库锁:检查并发访问冲突
性能调优断点
# 监控线程创建
(gdb) b pthread_create
# 监控数据库操作
(gdb) b SQLite::Statement::executeStep
# 监控内存分配
(gdb) b malloc
(gdb) b free
4.7 性能特点与限制
优势
-
简单直观:架构清晰,易于理解和维护
-
快速开发:基于成熟的SQLite和nlohmann/json库
-
跨平台:Linux服务端 + Windows/Linux客户端
当前限制
-
并发性能:一连接一线程模型,高并发时线程开销大
-
消息持久化:离线消息未存储,用户离线时消息丢失
-
负载均衡:单机部署,无集群支持
-
安全性:明文传输,缺少加密和认证机制
优化建议
-
引入线程池:减少线程创建销毁开销
-
消息队列:支持离线消息存储和推送
-
连接池:优化数据库连接管理
-
SSL/TLS:加密网络传输
-
Redis缓存:提升在线状态查询性能
5 项目总结
5.1 技术栈总览
|
层次 |
技术选型 |
说明 |
|---|---|---|
|
客户端UI |
Qt6 Widgets |
跨平台GUI框架,丰富的控件库 |
|
客户端网络 |
QTcpSocket |
Qt网络模块,TCP长连接 |
|
服务端框架 |
Linux C++ |
多线程服务器,一连接一线程 |
|
数据库 |
SQLite + SQLiteCpp |
轻量级嵌入式数据库 |
|
序列化 |
nlohmann/json |
现代C++ JSON库 |
|
协议设计 |
长度前缀 + JSON |
自定义二进制协议 |
5.2 架构优势
-
开发效率高:基于成熟开源库,快速原型开发
-
部署简单:单机部署,无复杂依赖
-
易于调试:架构清晰,调试断点明确
-
跨平台性:客户端支持Windows/Linux
5.3 适用场景
-
学习项目:理解网络编程和数据库操作
-
小型团队:内部沟通工具(<100人)
-
原型验证:快速验证聊天功能需求
-
技术演示:展示Qt + C++技术栈
5.4 扩展方向
功能扩展
-
文件传输、图片分享
-
语音/视频通话
-
消息加密、数字签名
-
离线消息、消息历史
架构升级
-
微服务化、负载均衡
-
消息队列、缓存层
-
容器化部署
-
监控告警体系
这个项目为即时通讯系统提供了一个完整的基础框架,适合作为学习和进一步开发的起点。
更多推荐



所有评论(0)