Chatroom 是一个 Linux 课程设计项目,系统基于 C++20、POSIX socket 和 pthread 实现多用户命令行聊天室。
项目覆盖 Linux 网络编程、TCP 客户端/服务端模型、多线程会话管理、自定义二进制协议、文件持久化、配置文件读取和命令行交互等课程设计要点。系统支持账号注册与密码登录、群聊、私聊、历史消息查询、文件传输与管理、管理员公告与踢人、服务端优雅关闭与持久化存储。
| 要求 | 版本 |
|---|---|
| 操作系统 | Linux / WSL Ubuntu 20.04+ / 任何支持 POSIX socket 的 Unix-like 环境 |
| 编译器 | GCC 11+(支持 C++20) |
| CMake | >= 3.16 |
| 额外依赖 | 无(仅标准库和 POSIX API,SHA-256 自实现) |
cmake -S . -B build
cmake --build build -j关于 clock skew warning:在 WSL 访问 Windows 文件系统(/mnt/d/...)时,CMake 可能报告
Clock skew detected警告。这是因为 WSL 和 Windows 的文件时间戳存在微小差异。此警告 不影响编译结果,可以忽略。如需消除,可在 Linux 原生文件系统(如 ~/projects/)上构建。
# 单元测试
./build/chat_tests
# CTest
cd build && ctest --output-on-failure
# 集成测试(需要 Python 3)
python3 tests/integration_test_v3.py项目根目录提供 server.conf 和 server.conf.example。服务端默认读取当前工作目录下的 server.conf,也支持通过 -c 指定配置文件路径。
# 服务端配置文件
port=9090
storage_root=storage
max_file_size=52428800 # 50 MiB
history_limit=50 # /history 默认返回条数# 使用默认配置
./build/chat_server
# 指定配置文件
./build/chat_server -c /path/to/server.conf
# CLI 参数覆盖配置文件
./build/chat_server -p 9091 -s /data/storage按 Ctrl+C 可优雅关闭服务端。
./build/chat_client 127.0.0.1 9090| 命令 | 说明 |
|---|---|
/register <user> <pass> |
注册新账号(第一个注册的用户自动成为管理员) |
/login <user> <pass> |
登录聊天室 |
/all <message> |
发送群聊消息 |
/whisper <user> <message> |
发送私聊消息 |
/history [N] |
查看最近 N 条消息(默认 50 条) |
/sendfile <path> |
上传本地文件 |
/getfile <file_id> <path> |
下载文件到本地路径 |
/delfile <file_id> |
删除文件(普通用户只能删自己的,管理员可删任意) |
/files |
查看服务端文件列表 |
/users |
查看在线用户列表 |
/kick <user> |
踢出用户(仅管理员) |
/announce <message> |
发送公告(仅管理员,所有用户可见) |
/help |
显示帮助 |
/quit |
断开连接并退出 |
- Linux TCP socket 编程:服务端监听、客户端连接、数据收发和异常断开处理
- 多线程并发模型:每个客户端会话独立处理,广播路径使用互斥锁保护共享状态
- 自定义应用层协议:12 字节固定头部和变长 payload,整数采用网络字节序
- 命令行交互:客户端解析
/register、/login、/all、/whisper、/sendfile等命令 - 文件与状态持久化:用户、消息事件、文件索引和上传文件保存到本地
storage/ - 服务端运维能力:配置文件、结构化日志、
Ctrl+C优雅关闭和基础管理员命令
- 首次使用需
/register <用户名> <密码>注册账号 - 密码使用 SHA-256 + 随机盐哈希存储,不明文保存
- 第一个注册的用户自动获得管理员权限
/all <消息>向所有在线用户广播/whisper <用户> <消息>仅对方可见- 所有群聊消息持久化存储,新用户登录时自动同步
/history查看最近 50 条消息/history 100查看最近 100 条- 包含群聊消息、系统通知和文件事件
- 上传:
/sendfile <路径>,自动分配唯一 file_id,支持断点检测 - 下载:
/getfile <file_id> <路径>,分块传输 - 列表:
/files查看所有文件 - 删除:
/delfile <file_id>,用户可删自己的文件,管理员可删任意文件 - 大小限制:通过
server.conf的max_file_size配置,默认 50 MiB
/kick <用户>强制踢出指定用户/announce <消息>向所有用户发送系统公告- 仅第一个注册的用户拥有管理员权限
- SIGINT 优雅关闭
- 客户端异常断开不影响服务端和其他用户
- 上传中断自动清理临时文件
- 带时间戳的结构化日志输出
自定义二进制协议 v3,详见 PROTOCOL.md。
报文格式(12 字节头 + 变长 payload):
[4B magic "CHAT"][2B version=3][2B type][4B payload_len][payload...]
主要消息类型(28 种):
| 类型 | 值 | 方向 | 说明 |
|---|---|---|---|
| REGISTER_REQ/RESP | 21/22 | C<->S | 账号注册 |
| LOGIN_REQ/RESP | 1/2 | C<->S | 密码登录 |
| CHAT_SEND/BROADCAST | 3/4 | C<->S | 群聊 |
| WHISPER_SEND/RECV | 17/18 | C<->S | 私聊 |
| HISTORY_REQ/RESP | 23/24 | C<->S | 历史查询 |
| FILE_UPLOAD_*/EVENT | 5-8 | C<->S | 文件上传 |
| FILE_DOWNLOAD_* | 9/10 | C<->S | 文件下载 |
| FILE_LIST_REQ/RESP | 19/20 | C<->S | 文件列表 |
| FILE_DELETE_REQ | 25 | C->S | 文件删除 |
| KICK_REQ/NOTIFY | 26/27 | C<->S | 踢人 |
| ANNOUNCE_REQ | 28 | C->S | 管理员公告 |
| SYSTEM_BROADCAST | 16 | S->C | 系统通知 |
| USER_LIST_REQ/RESP | 14/15 | C<->S | 在线列表 |
| SYNC_BEGIN/END | 11/12 | S->C | 历史同步 |
| ERROR_MSG | 13 | S->C | 错误消息 |
所有运行时数据存储在 storage/ 目录下(已配置 .gitignore 忽略):
| 文件 | 格式 | 说明 |
|---|---|---|
users.db |
hex_user|hash:salt|last_seen|role |
用户注册表(含密码哈希和角色) |
events.db |
id|kind|hex_fields... |
聊天、文件、系统事件日志 |
files.db |
hex_fields... |
文件元数据索引 |
files/<id>_<name> |
原始二进制 | 已上传的文件 |
# 1. 克隆并构建
git clone <repo> && cd chatroom
cmake -S . -B build && cmake --build build -j
# 2. 配置
cp server.conf.example server.conf
vi server.conf
# 3. 启动(后台运行)
nohup ./build/chat_server -c server.conf > server.log 2>&1 &
# 4. 客户端连接(同机)
./build/chat_client 127.0.0.1 9090# 服务端启动后,其他机器通过局域网 IP 连接
./build/chat_client 192.168.1.100 9090- 本项目为教学/课程设计用途,不建议用于生产环境
- 无 TLS 加密,数据明文传输
- 管理员权限仅限第一个注册用户,无法动态调整
- 密码哈希使用自实现的 SHA-256,生产环境建议使用 OpenSSL/libcrypto
- 存储使用简单文本文件,高并发场景建议使用数据库
- WSL 下通过 /mnt/ 访问 Windows 文件系统时可能出现 clock skew 警告,不影响功能
本仓库中的代码与文档基于 MIT License 开源。