基于Qt的安全即时通讯软件服务器端设计
2017-02-13窦立君韩坷罕闫志刚
窦立君 韩坷罕 闫志刚
【 摘 要 】 论文详细介绍了如何基于Qt开发具有用户注册、用户资料维护、用户列表下发、登录校验、消息转发、文件传输等功能的安全即时通讯软件服务器端。
【 关键词 】 qt;消息转发;服务器端;文件传输
Design of Network Chat Software Server Based on Qt
Dou Li-jun 1 Han Ke-han 1 Yan Zhi-gang 2
(1.Nanjing Forestry University JiangsuNanjing 210037;2.Dongfang Electronics Co.,Ltd. ShandongYantai 264000)
【 Abstract 】 The paper describes in detail how to develop a secure instant messaging server, which is based on Qt, which is user registration, user data maintenance, user list, login verification, message forwarding, file transfer and so on.
【 Keywords 】 qt; message forwarding; server; file transfer
1 引言
随着聊天软件应用在人们生活中各方面,人们也变得越来越重要重视聊天软件的存在,因为聊天软件在很大程度上为人民的生活办公提供了便利,人们可以通过互联网进行信息的有效收集和整理,以及与不同地方的人交流。
目前的聊天软件基本都是由服务器端和客户端两部分组成,客户端有Web版的和本地版的,无论哪种版本,它们都需要通过与服务器端的通信来实现最终功能。
本文通过对服务器端的功能分析、安全性、工作流程、关键代码设计等方面,来阐述安全聊天软件服务器端的设计过程。
2 系统分析
服务器聊天系统很重要的组成部分,所以对于服务器的功能需求分析是非常重要的,正确完整的分析,是成功构建一个聊天系统服务器的第一步。
能够成功地分析好服务器的需求,对于后面设计服务器的模块工作是不可或缺的,所以在这里,首先进行的就是关于这个即时聊天系统服务器的需求分析。
2.1 登录校验
输入:来自客户端的用户名和密码;
处理流程:与数据库中的用户名和密码匹配,并反馈结果给客户端;
输出:匹配成功或失败。
2.2 用户注册
输入:来自客户端的用户名和密码;
处理流程:在数据库中写入新用户名和密码,并反馈结果给客户端;
输出:新建成功或失败。
2.3 消息转发
输入:客户端所发送的聊天信息;
处理流程:根据所要发送到的用户名进行转发,用户不在线时另作处理;
输出:转发信息给发往方。
2.4 文件传输
输入:客户端所发送的文件数据;
处理流程:直接转发到发往方;
输出:转发数据给发往方。
2.5 用户资料维护
输入:客户端所发送的更新请求;
处理流程:按请求更新数据库中对应的数据;
输出:更新成功或失败。
2.6 用户列表下发
输入:用户登录成功;
处理流程:当某用户登录成功后,下发在线用户列表给该用户;
输出:在线用户列表。
根据服务器端的需求分析,进行功能模块的划分:封包解析模块、封包生成模块、封包分发模块、数据存储模块、用户注册模块、用户登录模块、文本信息转发模块、离线文本信息转发模块、文件传输模块、用户列表下发模块、用户资料模块、超时检测模块,这些模块既有独立完成相关功能,也有相互协调,合作完成最终任务。
3 安全性分析
现在大家使用的安全即时通讯软件基本都是使用数据报协议UDP。UDP和传输控制协议TCP都是传输层协议,但UDP是一种面向无连接的传输协议,这种协议在进行双方数据传输时,发送方只要知道接收方的地址和端口号就可以向接收方发送数据。这种协议带来高速便捷的数据传输,但不提供数据传送的安全保障机制,因此数据包传输不可靠,丢包率高。具体实现时要设计一种机制来对用户传递的数据提供一种丢失检测。
对于文件传输,如果是在同一局域网内,或者双方都具有公网IP,只要直接建立TCP连接就可以传文件。但是,在互联网上,实际的情况比这更要复杂,客户端有可能处于同一NAT或不同的NAT之内,客户端之间要直接通信比较困难。在此处的文件传输案例中,就可以使用“TCP”打洞技术,或者通过服务器中转,来穿透NAT进行数据收发。
4 工作流程
有了完整的模块划分,现在需要的就是构建服务器的工作流程,让服务器运转起来。本聊天服务器的核心工作流程,简单地说,就是不断把消息包分类摊派到各个不同处理模块上的过程。
服务器在指定的端口上侦听数据包,当接收到数据包后,首先调用封包解析模块对数据包进行解析,获取命令类型后,再根据命令类型的不同来调用不同的模块。不同的模块处理完成后,再调用封包生成模块来打包结果,把处理结果发送给客户端。
当接收到的是登录命令时,将调用登录管理模块来判断是否可以登入系统,不管是否能登入,都把结果打包返回给客户端。如果能成功登入,则继续调用用户列表下发模块,把在线用户列表打包发送给客户端。
当接收到的是注册命令时,将调用用户注册模块来往系统中添加新用户,注册模块会调用数据存储模块进行处理,然后把结果打包返回给客户端。
当接收到的是资料更新命令时,将调用资料管理模块,资料管理模块又会调用数据存储模块进行处理,处理完成后,把结果反馈给客户端。
当接收到的是文本消息时,将调用文本消息转发模块进行处理,该模块从解析得到的结果中,获取所要发送往的客户端,然后进行转发。如果检测到所要发往的客户端不在线,则转入离线消息模块处理。
用户登录后,客户端会定时发送心跳包到服务器,服务器自动维护此在线状态列表,并定时执行超时检测模块,把超时的用户从在线列表中删除。
5 关键代码设计
聊天服务器的工作流程比较简单,即:收到消息→处理消息→转发处理后的消息。聊天服务器启动时在特定的端口监听,当有数据到达时,自动判断消息类型,进行不同的处理,然后根据处理结果,把它发送给客户端。实现中,消息的接收和发送,以及判断消息类型,都比较简单,工作量较大的则是处理消息的部分。因为有很多不同的命令,对应的,也有不同的处理过程,所以设计中,把这些处理过程分离成单独的处理逻辑,在类中表现为不同的函数。本模块的设计并不包含图形用户界面相关的部分,当最终的服务器软件需要搭配图形界面时,只需要在聊天服务器模块中定义相关的信号,并在合适的时候发出信号。图形界面程序就可以通过聊天服务器模块的信号和它的槽进行连接,来实现显示更新等功能。
5.1 聊天服务器端的类定义
为了利用Qt的信号和槽功能,聊天服务器类直接从QObject继承,具体代码如下 :
class ChatServer : public QObject
{ Q_OBJECT
public:
explicit ChatServer(QObject *parent = 0);
void start(quint16 port=4500); //启动服务
private:
void registerUser(const QString& id, const QString& password, const QHostAddress& addr, quint16 port);//注册用户
bool login(const QString& id, const QString& password, const QHostAddress& addr, quint16 port);//用户登录
void relayMessage(const QString& to, const QString& message, const QFont& font, const QColor& color, const QHostAddress& addr, quint16 port);//转发聊天消息
void sendFriendsList(const QHostAddress& addr, quint16 port); //发送用户列表
void feedback(const QHostAddress& addr, quint16 port); //反馈
void logout(const QHostAddress& addr, quint16 port); //注销
void keepAlive(const QHostAddress& addr, quint16 port); //激活
QUdpSocket *m_udpSender; //发送数据的UDP对象
QUdpSocket *m_udpReceiver; //监听数据的UDP对象
QHash
QHash
QHash
Storage m_storage; //数据存储对象
enum {onlineTimeout = 30}; //在线超时时间
private slots:
void processPendingDatagrams(); //网络数据处理
void checkTimeout(); //检查超时状态
};
在ChatServer类的实现中,需要注意名称表、主机表以及激活状态表的维护,它们是维持服务器工作状态的核心。为了实现快速查询,这几张表都采用Qt中的哈希表QHash进行存储。如:名称表是用户名到(主机,端口号)的映射,即通过用户名可以查询到对应的主机地址和端口号,在转发消息时就要使用到名称表。
5.2 超时检测
超时检测功能由定时器自动执行,以实现隔固定时间更新一次在线状态的功能。当到达时间点时,程序开始遍历激活状态表中的所有用户,检查其最后一次的心跳包时间与当前系统时间的差值是否超过指定的预期,如果没有,则表示用户仍然正常在线,如果超时,则作自动注销处理。具体代码如下:
void ChatServer::checkTimeout()
{ QList
QDateTime now = QDateTime::currentDateTime(); //获取当前系统时间
for (int i = 0; i < keys.length(); ++i) //遍历所有用户
{ if (m_aliveTimeHash.value(keys.at(i)).secsTo(now) > onlineTimeout) //检查用户是否超时
{ qDebug() << trUtf8("%1 timeout").arg(keys.at(i));
QStringList list = keys.at(i).split(" ");
QHostAddress addr;
addr.setAddress(list.at(0).toInt());
quint16 port = list.at(1).toInt();
logout(addr, port); //用户超时的时候作注销处理
}}}
6 结束语
关键代码介绍之后,其它功能的代码的接口规范及实现也就相对容易了,这里就不再作介绍。服务器端软件设计完成之后,配合客户端软件完成了消息的传递及转发,客户端文件的传输及服务器端日志的记录等功能。后期,还需要继续在数据的传输安全性和可靠性方面做好优化,做好客户端其它的扩展功能的支持,提高客户端用户对服务器端响应和支持的体验。
参考文献
[1] 丁林松,华丽琴.Qt4图形设计与嵌入式开发[M].北京:人民邮电出版社.2009.
[2] (英)萨默菲尔德.Qt高级编程[M].北京:电子工业出版社.2011.
[3] 吴迪.零基础学Qt4编程[M].北京:北京航空航天大学出版社.2010.
[4] 代勇.Visual C++网络通信编程技术详解[M].北京:机械工业出版社.2011.
[5] 行天. 聊天的危险看即时通讯常见安全问题[J]. 计算机与网络,2007,09:34-35.
[6] 李延松,余隋怀,吴博. 基于Socket的安全即时通讯软件的设计[J]. 科学技术与工程,2007,12:2974-2977.
基金项目:
基于MDA技术的Web应用平台研究(科技创新)(163070054); 软件服务外包专业实训体系改革(高教研究)(163070644)。
作者简介:
窦立君(1977-),男,江苏泰州人,硕士;主要研究方向和关注领域:计算机应用。