Skip to content
简单群聊软件实现
C++ QMake
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
client
common
img
README.md

README.md

ChatRoom Document (Final)

due 12.23 23:59:59

finished 12.23 10:30:00

简单群聊软件实现

本repo只有client端. server端暂不上传.

动态/静态编译均可,如需静态编译请自行查询qt静态编译方法.

采用增量开发

尽可能实现更多的功能,不强求实现所有功能,但是尽量完整完成所有基本功能.

Demo

alter text

alter text

alter text

alter text

alter text

alter text

alter text

alter text

alter text

...

还有很多,如文件传输(可取消发送,中途取消发送,断点续传等)、消息回看、设置字体大小及颜色等(下次登录仍可保存不丢失)等...

私以为本作品比linux上wine QQ/TIM更为方便,不易掉线,传输文件快速,为校园网内极佳聊天软件(逃

此版本client端可支持跨平台,但未做条件编译,所以需要手动修改几个#include的头文件. (欢迎pull request来修复这个bug)


开发环境

client

  • C++
  • QT

server

  • C++
  • Mysql

TODO

首先需要设计

  • 报文格式
  • 数据库表

基本要求

  • 用户登录
  • 用户改密
  • 重复登录,后者踢掉前者
  • 可以看到在线的其他用户
  • 可以向某一个人发送数据
  • 可以向全体发送数据
  • 可以传送文件
  • server需要记录log
  • client信息尽量存放在server端

安全

  • 数据库password字段需要加密

Bonus

  • 可以传输jpg图片、git图片,要求能显示、有动画效果(3')
  • client可以指定向哪些人发送消息(1')
  • server的log采用xml格式(1')
  • 修改用户设置(2')
  • 采用OpenSSL(2')
  • 完成手机端client(5')
  • 其他特色功能可根据实际情况加分(实现了F1快捷键发送、html格式传输图片)

协议栈

一共六种报文:

  • 报道包

    • client: 发送用户密码
    • server: accept/reject和原因
  • 上线/下线包

    • 只有server对client. 给所有在线用户发
    • 类型:上线/下线
    • 附加用户信息
  • 文本信息发送包

    • 参考sj作业课件
    • 文件包可以在文件信息发送包的类型里面
  • 设置包

    • 双向,用于设置GUI
    • 传配置文件(config.json)
  • 在线文件notify包

  • 文件数据包

报文格式

报头格式

大小 描述
2B 报文大类型
2B 细分类型/应答类型
4B 长度(不包括报头长度)

报道包

client -> server

大小 数值 描述
2B 0x10 类型
2B 0x00
0x01
登录
注册
4B 长度
32B 用户名
32B 密码
大小 数值 描述
2B 0x10 类型
2B 0x02 更改密码
4B 长度
32B 用户名
32B 原密码
32B 现密码

server -> client

大小 数值 描述
2B 0x80 类型
2B 0x00
0x01
0x02
0x03
0x04
0x05
0x06
0x07
0x08
0x09
0x0a
登录/注册 成功
登录成功(但是踢了原来登陆的人)
登录失败,密码错误
登录/更改密码失败,用户名不存在
登录失败,需要强制改密
注册失败,用户名已存在
注册失败,用户名不符合要求
注册失败,密码不符合要求
更改密码成功
更改密码失败,原密码错误
更改密码失败,现密码不符合规范
4B 长度

登录成功附加数据:
  • 0x00 0x01
大小 数值 描述
19B 上次登录时间
4B 用户数量 n
33B * n 所有用户信息

注:第33B为字符'0'(ascii不为0)时代表离线,为'1'代表在线

其他无附加数据

上线/下线包

server -> client

大小 数值 描述
2B 0x81 类型
2B 0x00
0x01
上线
下线
4B 长度
32B 用户名

注:此处client若收到的下线包是自己,则代表着有人抢占该账户,client自动exit

文本信息发送包

client -> server

报头:

大小 数值 描述
2B 0x12 类型
2B 0x00
0x02
0x04
0x05
给1个或多个文本信息
给1个或多个发文件信息
请求给自己发文件内容
请求回看n条信息
4B 长度

注:在发单个或多用户包时,用户如果需要回显需要自己给自己发文本,或者直接在client自己解决,否则server不负责给发送者发该包;而all会直接给所有client发。

附加数据:

  • 0x00
大小 描述
4B 用户数量 n
32B * n 用户名
to end 文本信息

用户数量为1,且用户名为空则代表发给all

  • 0x02
大小 描述
4B 用户数量 n
32B * n 用户名
64B 文件名
to end 文件信息
  • 0x04
大小 描述
4B 文件标识
  • 0x05
大小 描述
4B 要回看的长度
32B 会话对方的用户名

TODO 倘若用户名为空,则代表all 注:回看的数据来源是用户自己的收发信息表

server -> client

报头:

大小 数值 描述
2B 0x82 类型
2B 0x00
0x01
0x02
0x03
文本消息
文件信息
文件内容
清屏
4B 长度

附加信息:

  • 0x00
大小 描述
32B 来源用户名
32B 去向用户名
19B 时间
to end msg 文本信息

来源或者去向用户名为空则代表着自己发送在all和all中发给自己

  • 0x01
大小 描述
32B 来源用户名
32B 去向用户名
19B 时间
64B 文件名
4B 文件标识
  • 0x02
大小 描述
32B 来源用户名
19B 时间
64B 文件名
4B 文件标识
to end 文件内容

必为all

TODO 注:本部分完全可以不添加时间、用户名、长度;但是依旧加上,以作额外可能的处理。

  • 0x03

无附加数据

设置包

client -> server

大小 数值 描述
2B 0x13 类型
2B 0x00 填充
4B 长度
to end 配置文件(config)

server -> client

大小 数值 描述
2B 0x83 类型
2B 0x00 填充
4B 长度
to end 配置文件(config)

注:只有确认登录成功之后,server才会发此包,而client在接收到该包后才会进入真正的用户界面。 同时,由于是登录后的操作,因而不必加上用户名。

在线文件notify包

在线文件发送流程
传输过程中,默认将文件按照每3964字节划分为多个文件块
server在传输中仅负责转发,不修改和保存数据


`sender`向`receiver` 发送 **请求发送包**,附加文件信息
`receiver`收到**请求发送包**后,选择是否接收:
--不接收:向`sender`发送**拒绝接收包**,块号为0
----`sender`收到**拒绝接收包**后,显示对方拒收,传输结束
--接收:向`sender`发送**接收文件包**,块号为0, 进入数据传输循环

循环传输过程:
`sender`收到接收文件包,使用**文件数据包**将对应块号的文件发送给`receiver`
`receiver`收到**文件数据包**后, 向`sender`发送**接收文件包**,块号为之前块号+1
--如果`sender`在传输过程中选择中断传输,发送**拒绝发送包**,块号为之前收到的**接收文件包**的块号
----`receiver`收到**拒绝发送包**之后,显示对方中断发送
--如果`receiver`在传输过程中选择中断传输,发送**拒绝接收包**,块号为之前发送的**接收文件包**的块号+1
----`sender`收到**拒绝接收包**之后,显示对方中断接收
--`sender`发送最后一个文件块时,将**文件数据包**的块号改为**0xFFFF**
----`receiver`收到**文件数据包**的块号为**0xFFFF**时,表示传输结束
大小 数值 描述
2B 0x14 类型
2B 0x00
0x01
0x02
0x03
请求发送
取消发送
同意接收
取消接收
4B 132 长度
132B 附加信息

sender -> server and server -> receiver

  • 0x00 请求发送
大小 描述
32B 用户名(发送方)
32B 用户名(接收方)
64B 文件名
4B 文件大小
  • 0x01 取消发送
大小 描述
32B 用户名(发送方)
32B 用户名(接收方)
64B 文件名
4B 文件块号

receiver -> server and server -> sender

  • 0x02 同意接收
大小 描述
32B 用户名(发送方)
32B 用户名(接收方)
64B 文件名
4B 文件块号
  • 0x03 取消接收
大小 描述
32B 用户名(发送方)
32B 用户名(接收方)
64B 文件名
4B 文件块号

文件数据包

注:文件数据包仅用于用户一对一在线转发文件

大小 数值 描述
2B 0x15 类型
2B 0x00 填充
4B 4096 长度
4096B 附加信息
  • 附加信息内容
大小 描述
32B 用户名(发送方)
32B 用户名(接收方)
64B 文件名
4B 文件块号
3964B 文件内容

数据库

user_info

系统只需要一个表

uname char(32) pwd char(32) last_login_time datetime user_set mediumblob
zhongyuchen xxxx 2018.12.13 20:12 xxxx
zhaiyuchen xxxx 2018.12.12 14:22 xxxx
liuyitao xxxx 2018.12.13 15:32 xxxx

注:在用户从未登录的状态下,其上次登录时间设置为0000.00.00 00:00:00表示下次需要强制改密

username_msgtable

系统为每个用户各自维护一个收发信息表,表名为username_msgtable,记录该用户发送/接受信息时的标识、时间、来源、信息类型和内容标识,并保留适当的索引,需要时可查找每次传输的内容。

主要功能:

  • 回看历史消息

e.g. zhaiyuchen_msgtable

um_id int unsigned send_time datetime from_user char(32) to_user char(32) cid int unsigned ctype char
1 2018.12.1 20:12 zhongyuchen "" 0 m
2 2018.12.13 20:13 zhaiyuchen zhongyuchen 0 i
3 2018.12.13 13:44 zhongyuchen zhaiyuchen 1 d
4 2018.12.13 13:44 "" "" 2 d

>第一条表示zhognyuchen发在群聊窗口 >第二条表示自己发给zhongyuchen >第三条表示zhongyuchen发给自己的 >第四条表示自己发在群聊窗口的 >TODO

注:文件类型通过后缀直接判断即可(除msg),若为msg则表示发送消息;在这里文件只区分文本和非文本。


text_containfile_contain

系统为所有用户共同维护一个文本信息表和一个文件信息表,记录所有用户传输的所有文本和文件的具体内容,所有文本内容由msg标识唯一确定,所有文件信息由文件标识唯一确定

mid int unsigned mcontain mediumtext
1 hello,world!

fid int unsigned fsize int fname char(64) fcontain mediumblob
1 1456 test.jpg 00010100101001010...
2 123213 test.txt hello,world!

注:数据库大小写区分,且client和server统一使用utf8编码

You can’t perform that action at this time.