Qt5实现的局域网通信工具,支持公网。类似软件百度一大把,但是还是想整理一份属于自己的专属QQ。支持跨平台。
本文主要介绍利用Qt实现局域网通信的主要实现流程和一些技术知识点的设计说明。
这款局域网通信软件是基于Qt的实现的C/S架构通信,通信功能全部采用QTcpSocket完成的。该软件分为2部分,一部分是服务端,一部分是客户端。
消息通信采用QJsonValue的格式进行封装,方便封装和解析。
整个设计可以大致分为服务端、客户端,服务端功能相对比较单一,仅仅做了客户端的消息管理和转发等。数据库读写等。客户端相对较为丰富。包括好友管理、群组管理、tcp消息管理,数据库管理,
整个项目设计的功能的设计流程图大致如下所示:
图2-1
本项目的采用Qt进行设计开发,Qt版本为5.7.0,在后续代码维护和修改的时候建议使用该版本或更高的版本。
本设计中主要使用4个大类,一个QTcpServer,另外一个是QTcpSocket,主要是用于通信的,但是他们通信的时候采用了QJsonValue的数据格式进行交互,下面针对这个几个主要的模块进行简单介绍下。最后就是数据库QDataBase
m_tcpServer = new QTcpServer(this);
connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(SltNewConnection()));
该类为TCP的通信类,主要是链接服务器与客户端的。当连接或者断开开都可以获取该消息通知。并做出相应的处理。
connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(SltReadyRead()));
connect(m_tcpSocket, SIGNAL(connected()), this, SLOT(SltConnected()));
connect(m_tcpSocket, SIGNAL(disconnected()), this, SLOT(SltDisconnected()));
该类为TCP通信的参数传递类,用于封装传递消息的。其格式如下:
图3-2-1 JSON数据封装
然后数据输出为:
{"data":{"name":"xiaoni","passwd":"123456"},"from":1,"type":2}
分别表示为:
Type: 消息传输类型(比如登陆、注册、消息发送、文件发送等)
From: 表示发送者的id。
Data:传输数据的封装对象,里面可能是json数组或则直接就是对象
// 对于这个json格式的解析如下:(其他格式均是如此)
// data 的 value 是对象
if (dataVal.isObject()) {
QJsonObject dataObj = dataVal.toObject();
QString strName = dataObj.value("name").toString();
QString strPwd = dataObj.value("passwd").toString();
m_nId = DataBaseMagr::Instance()->CheckUserLogin(strName, strPwd);
qDebug() << "Login" << strName << strPwd << m_nId;
// 返回客户端
QJsonObject json;
json.insert("id", m_nId);
json.insert("code", -1 == m_nId ? m_nId : 0);
json.insert("msg", -1 == m_nId ? "error" : "ok");
if (-1 != m_nId) Q_EMIT signalConnected();
// 发送查询结果至客户端
SltSendMessage(Login, json);;
}
该类为数据库引擎类,在本设计中,服务端和客户端均采用数据库的方式进行数据的保存。
服务端:
创建用户数据库表
query.exec("CREATE TABLE USERINFO (id INT PRIMARY KEY, name varchar(20), "
"passwd varchar(20), status INT, groupId INT, lasttime DATETIME);");
|
|
|
|
|
|
|
|
|
|
|
|
创建用群组数据库表
query.exec("CREATE TABLE GROUPINFO (id INT PRIMARY KEY, groupId INT, name varchar(20), "
"userId INT, identity INT)");
|
|
|
|
|
|
|
|
|
|
客户端:
// 创建历史聊天表
query.exec("CREATE TABLE MSGINFO (id INT PRIMARY KEY, userId INT,"
"type INT, direction INT, content varchar(500))");
|
|
|
|
|
|
|
|
|
|
// 创建我的好友表
query.exec("CREATE TABLE FRIEND (id INT PRIMARY KEY, name varchar(50))");
|
|
|
|
// 创建群组表
query.exec("CREATE TABLE MYGROUP (id INT PRIMARY KEY, name varchar(50))");
|
|
|
|
4 界面设计
服务端界面仅仅是一个消息记录的方式,大部分功能都是做的消息转发功能,没有图像界面,因此界面很单一,在用户上下线的时候会提示。
图4-1 服务端界面
客户端界面相对比较复杂,界面风格仿照QQ的主面板设计,分为好友管列表,群组管理列表。
图4-2 客户端主界面
图4-3 私聊窗口
聊天界面采用QWidget的绘制,模仿QQ聊天气泡进行设计的,目前支持功能文件传输功能(服务器转发,先将要发送的文件传给服务器,然后通过服务器将该文件消息发送至对端客户,对端客户可以选择下载文件,也可以选择不下载文件)。
消息聊天机制:客户端将要发送的文本消息封装成QJsonValue格式的数据,通过服务器进行查找,如果对端客户在线,那么直接将该消息发送过去,不在线的用户不处理,可拓展为离线消息(保存最近100条消息,当下次该用户上线时,服务器将该消息推送给他)
文件发送机制:采用文件分片的方式将整个文件拆分成byte进行发送,每次发送50个byte,在局域网可以达到10M/S的传输速率。
图4-4群组聊天
群组聊天机制:当该群组里面的某个好友主动发起会话时,服务器会自动吧该消息转发给其他在线的组成员,并简单的封装下,是谁发送的消息。以此进行区分。
图4-5 登陆界面
在本设计中,添加了一个用户登陆的功能,因为走tcp流程,需要进行用户认证,点击登陆时,通过tcp发送认证消息至服务端,服务器查询服务器的数据库文件,如果查询到,返回JSON格式的数据给该客户端,并通过认证,可登陆主界面,否则如上弹出登陆校验失败的错误提示框。
用户注册:方法也是通过tcp发送注册消息至服务端,并获取返回的json数据。
1、数据库聊天记录保存,当第一次加载该消息框时,会自动加载最近10条记录,并显示,如果想要获取全部的聊天记录,可直接点击聊天窗口上的历史记录按钮即可。
2、好友管理,目前只添加用户添加功能,用户删除功能没做,可以自行添加。
3、群组管理,与好友管理方法类似,删除功能为做。
4结语
好友管理类使用的QListWidget进行封装处理的,理聊天的气泡界面也是通过QPainter进行绘制,自己管理的列表类,支持鼠标滚轮滑动。
5、代码下载
编译代码前,请先阅读代码说明。
下载地址:https://download.csdn.net/download/nigoole/10819039