?
?
?
通讯项目——仿QQ聊天程序
?
详细设计说明书
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
一、引言
此项目为验证Java语言Socket部分学习成果,本文档将对此项目进行详细说明。
二、总体设计
模块划分
本项目共分为服务器端和客户端两大模块。
服务器端共有6个模块:
等待客户端的连接,一但连接成功则分发给线程处理;
接收客户端传递来的消息;
向客户端回复应答消息;
连接数据库并进行增删改查等操作;
转发A客户端的消息给B客户端;
处理客户端下线。
客户端共有5个模块:
连接服务器;
向服务器发送消息;
接收服务器的应答消息;
接收有服务器转发的另一客户端消息;
断开与服务器的连接。
?
功能划分
本项目所实现的功能有:
注册,登陆,添加好友,单人聊天。
其中添加好友做了验证处理,单人聊天支持:窗口抖动,发送表情,传送文件等特色功能。
技术点支持
本项目使用Java语言编写,所涉及到的技术点有:Socket,Thread,GUI,JDBC等。
环境支持
Eclipse,MySQL
三、详细设计
数据库设计
数据库共四张表格,见下图:
由上至下分别为:组群信息表,组群与用户联系表,用户信息表,用户好友关联表。
?
Groups表结构如下:
?
Groupsusers表结构如下:
?
Users表结构如下:
?
Usersfriends表结构如下:
?
通信协议
消息数据类型定义
类型 |
说明 |
byte |
用于表示消息类型,一个字节的整数 |
Unsigned Integer? |
网络字节顺序 |
Octet String? |
定长字符串,不足在右边补齐二进制0 /0 |
?
消息类型
消息类型 |
标志值 |
描述 |
1 注册请求消息 |
0x01? |
客户端发送注册请求数据给服务器 |
2 注册应答消息 |
0x02? |
服务器返回注册结果 |
3 登录请求消息 |
0x03? |
客户端发送QQ号码和密码的消息请求登录 |
4 登录应答消息 |
0x04? |
服务器返回的登录结果应答消息 |
5 在线好友列表消息 |
0x05? |
服务器发送给登录成功客户端的其他好友列表消息 |
6 好友上线消息 |
0x06? |
服务器发送通知某用户好友上线消息 |
7 好友下线消息 |
0x07? |
服务器发送通知某用户好友下线消息 |
8 聊天消息发送 |
0x08? |
客户端发给服务器或服务器发给某客户端的文本聊天消息 |
9 文件传送消息 |
0x09? |
客户端发给服务器,或服务器发给某客户端的文件数据传送消息 |
10 文件传送应答 |
0x11? |
客户端发给服务器,或服务器发给某客户端的文件数据传送应答消息 |
11 截图消息发送 |
0x12? |
客户端发给服务器或服务器发给某客户端的截图消息 |
12 窗口抖动消息 |
0x13? |
客户端发给服务器或服务器发给某客户端的窗口抖动消息 |
13 创建组群请求消息 |
0x14? |
客户端发给服务器的创建组群消息 |
14 创建组群请求应答 |
0x15? |
服务器发送给客户端的创建组群应答消息 |
15 查找在线用户消息 |
0x16? |
客户端发给服务器查询在线用户的消息 |
16 查找在线用户应答 |
0x17? |
服务器应答客户端的查找消息结果 |
17 添加好友请求 |
0x18? |
客户端发给服务器请求加好友消息,或服务器发给被添加用户的加好友的请求消息 |
18 添加好友应答 |
0x19? |
服务器应答客户端加好友的结果 |
19服务器发送群组列表 |
0x21? |
登录后服务器发送个客户端该用户的群组列表 |
20查找组群请求 |
0x22? |
客户端发送给服务器的查找组群请求 |
21查找组群应答 |
0x23? |
服务器发送给客户端的查找组群应答 |
22添加组群请求 |
0x24? |
客户端发送给服务器的添加组群请求 |
23添加组群应答 |
0x25? |
服务器发送给客户端的添加组群应答 |
21群聊消息发送与接收 |
0x26? |
客户端发给服务器或服务器发给该群所有客户端的文本聊天消息 |
?
消息整体结构规则
结构 |
说明 |
Message Head? |
消息头 所有消息公共的消息头 |
Message Body? |
消息体 各种消息的消息体不同 |
?
消息头规则
字段名 |
数据类型 |
字节数 |
描述 |
totalLen? |
int? |
4? |
消息字节总长 包含消息头总长度 |
type? |
byte? |
1? |
消息类型 |
dest? |
int? |
4? |
消息目的地 消息发送给谁 |
src? |
int? |
4 |
消息源 谁发送的消息 |
?
具体消息结构定义
1、注册消息体结构
字段 |
数据类型 |
长度 |
描述 |
nikeName? |
Octet String? |
10? |
注册用户昵称 |
password? |
Octet String? |
10? |
注册用户密码 |
? | ? | ? |
注册的时候,消息头中的dest值为服务器的QQ号码 |
2、注册应答消息体结构
字段 |
数据类型 |
长度 |
描述 |
state? |
Octet String? |
10? |
服务器返回的注册结果应答,0为成功,消息头中的dest值为注册成功的QQ号码;非0为注册失败。 |
3、登录请求消息体结构
字段 |
数据类型 |
长度 |
描述 |
pwd? |
Octet String? |
消息总长减去消息头长度 |
登录用户的密码 |
4、登录应答消息体结构
字段 |
数据类型 |
长度 |
描述 |
state? |
byte? |
1? |
0:成功 1:账号错误 2:IP验证失败 |
?
5、好友列表消息体结构
字段 |
数据类型 |
长度 |
描述 |
||
listCount? |
byte? |
1? |
好友分组个数 |
||
ListCount? |
listName? |
Octet String? |
10? |
一个分组的名字 |
|
bodyCount? |
byte? |
1? |
本组内有多少个用户 |
||
组内的bodyCount个好友 |
bodyNum? |
int? |
4? |
组内一个好友的QQ号 |
|
nikeName? |
Octet String? |
10? |
好友昵称 |
||
如果有多组,后面的结构同 listCount个分组数据部分 |
6、好友上线消息体结构
字段 |
数据类型 |
长度 |
描述 |
无 |
无 |
消息头长度 |
消息头中包含消息类型 |
7、好友下线消息体结构
字段 |
数据类型 |
长度 |
描述 |
无 |
无 |
消息头长度 |
消息头中包含消息类型 |
8、聊天消息体结构????
字段 |
数据类型 |
长度 |
描述 |
msgContent? |
Octet String? |
消息总长减去消息头长度 |
聊天的消息内容 |
9、文件传送消息体结构
字段 |
数据类型 |
长度 |
描述 |
filename |
Octet String? |
10? |
传送的文件名字 |
fileData? |
byte? |
总长-消息头长(13)-256 |
文件内容 |
10、文件传送应答消息体结构
字段 |
数据类型 |
长度 |
描述 |
state? |
Octet String? |
10? |
被发送文件的客户端返回给服务器或服务器返回给发送文件的客户端的文件传送结果应答,0为接收,前者消息头中的dest值为服务器QQ号码,后者消息头中的dest值为发送文件的客户端的QQ号码;1为拒绝接收;2为发送成功;-1为发送失败。 |
11、截图发送消息体结构
字段 |
数据类型 |
长度 |
描述 |
fileData? |
待定 |
消息总长减去消息头长度 |
截屏得到的图片 |
?
12、窗口抖动发送消息体结构
字段 |
数据类型 |
长度 |
描述 |
无 |
无 |
消息头长度 |
消息头中包含消息类型 |
13、创建组群请求消息
字段 |
数据类型 |
长度 |
描述 |
GroupName? |
String? |
16? |
创建的组群名称 |
14、创建组群请求应答
字段 |
数据类型 |
长度 |
描述 |
GroupID? |
int? |
4? |
服务器生成的群ID |
15、查找在线用户消息
字段 |
数据类型 |
长度 |
描述 |
无 |
无 |
消息头长度 |
消息头中包含消息类型 |
16、查找在线用户应答消息体结构
字段 |
数据类型 |
长度 |
描述 |
|
userCount? |
int? |
4? |
用户数量 |
|
userCount个用户数据 |
nikeName? |
Octet String? |
10? |
一个用户的昵称 |
QQNum? |
int? |
4? |
一个用户的QQ号码 |
|
如果有userCount个用户,后面的结构相同 |
17、添加好友请求消息体结构
字段 |
数据类型 |
长度 |
描述 |
QQNum? |
int? |
4? |
要添加的好友的QQ号码 |
18、添加好友应答消息体结构
字段 |
数据类型 |
长度 |
描述 |
QQNum? |
int? |
4? |
被添加的好友的QQ号码 |
nikeName? |
Octet String? |
10? |
被添加的好友的昵称 |
19、服务器发送群组列表
字段 |
数据类型 |
长度 |
描述 |
|
GroupCount? |
int? |
4? |
组群数量 |
|
userCount个用户数据 |
GroupName? |
Octet String? |
16? |
一个组群的名称 |
? |
GNum? |
int? |
4? |
一个组群的ID |
? |
GMasterNum? |
int? |
4? |
群组的ID |
如果有GrouopCount个组群,后面的结构相同 |
20、查找组群消息
字段 |
数据类型 |
长度 |
描述 |
无 |
无 |
消息头长度 |
消息头中包含消息类型 |
21、查找组群应答
字段 |
数据类型 |
长度 |
描述 |
|
GroupCount? |
int? |
4? |
组群数量 |
|
userCount个用户数据 |
GroupName? |
Octet String? |
16? |
一个组群的名称 |
? |
GNum? |
int? |
4? |
一个组群的ID |
? |
GMasterNum? |
int? |
4? |
群组的ID |
如果有GrouopCount个组群,后面的结构相同 |
22、添加组群请求
字段 |
数据类型 |
长度 |
描述 |
GID? |
int? |
4? |
要添加的群的ID |
23、添加组群应答
字段 |
数据类型 |
长度 |
描述 |
|
userCount个用户数据 |
GroupName? |
Octet String? |
16? |
一个组群的名称 |
GNum? |
int? |
4? |
一个组群的ID |
|
GMasterNum? |
int? |
4? |
群组的ID |
?