返回项目

局域网聊天室

使用 C++17、WinSock、Win32 和 SQLite 构建的 Windows 局域网桌面聊天室。

年份2026
状态持续完善
技术栈C++17 · WinSock · Win32 · SQLite

这是一个面向 Windows 的局域网桌面聊天室。项目由图形客户端、TCP 服务端和单文件启动器组成,目标不是简单完成消息收发,而是把连接管理、协议解析、并发访问、数据持久化和桌面交互串成一套完整流程。

已实现功能

  • 注册、账号登录和游客进入
  • 公共聊天室与一对一私聊
  • 在线成员列表,以及在线、离开、忙碌和隐身状态
  • 群聊与私聊文件传输,单个文件最大 10 MB
  • 管理员公告、禁言、踢出和 IP 封禁
  • 账号、封禁记录、消息和服务端事件持久化
  • 中文 Win32 图形界面,消息气泡与会话列表分栏显示

程序结构

Chatroom.exe
  ├─ chatroom_server.exe  TCP 服务端
  ├─ cloud_chat.exe       Win32 图形客户端
  └─ runtime/             配置、数据库与接收文件

用户只需要启动 Chatroom.exe。启动器会检查本机 8888 端口,按需释放并启动服务端,等待监听就绪后再打开客户端。服务端已经运行时,新的客户端会直接复用它,因此同一台机器可以同时打开多个窗口进行测试。

服务端绑定所有网卡地址,局域网内的其他设备可以在客户端填写服务器的 IPv4 地址和端口进行连接。

通信协议

客户端和服务端通过 TCP 传输 UTF-8 文本行,每条命令以换行符结束,基本格式为:

TYPE|字段1|字段2|消息正文

例如,公共消息使用 MSG|内容,私聊使用 PM|目标昵称|内容,文件则由 FILE_BEGINFILE_CHUNKFILE_END 三类消息组成。

TCP 不保留消息边界,所以接收端维护独立缓冲区:一次 recv 收到多条消息时逐行取出,只收到半条消息时则继续等待。发送端使用 sendAll 循环发送,避免一次 send 只写入部分数据。

并发与状态管理

服务端采用“一条连接一个工作线程”的模型。全局互斥锁保护账号、在线用户、禁言状态和文件路由表;每个客户端还有自己的发送锁,防止多个线程同时向同一个套接字写入时产生数据交叉。

广播消息时,服务端会先在锁内复制接收者列表,再在锁外执行网络发送。这能缩短全局临界区,也避免慢客户端阻塞其他用户的状态更新。

客户端的接收线程只负责解析消息,再通过 PostMessageW 把事件交回 Win32 主线程更新界面,避免后台线程直接操作窗口控件。

数据持久化

服务端使用 SQLite 保存以下数据:

  • accounts:账号、密码摘要、昵称和权限
  • banned_ips:被封禁的 IP 地址
  • messages:公共消息和私聊记录
  • admin_events:禁言、封禁和公告等管理操作
  • server_events:连接与服务端运行事件

数据库开启 WAL 模式和线程安全连接选项,让读取、写入和多客户端处理可以更稳定地协作。

当前边界

这个版本定位于可信局域网和网络编程学习场景。目前通信未启用 TLS,密码使用 SHA-256 摘要而不是专门的密码哈希算法,文件传输也没有断点续传与完整性校验。若继续面向公网扩展,需要加入 TLS、Argon2id 或 bcrypt、随机盐、文件校验、传输确认以及更细致的权限模型。

更完整的协议、并发和文件传输设计记录见《局域网聊天室:从 TCP 连接到桌面交互》。