竇立君 韓坷罕 閆志剛
【 摘 要 】 論文詳細(xì)介紹了如何基于Qt開發(fā)具有用戶注冊(cè)、用戶資料維護(hù)、用戶列表下發(fā)、登錄校驗(yàn)、消息轉(zhuǎn)發(fā)、文件傳輸?shù)裙δ艿陌踩磿r(shí)通訊軟件服務(wù)器端。
【 關(guān)鍵詞 】 qt;消息轉(zhuǎn)發(fā);服務(wù)器端;文件傳輸
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 引言
隨著聊天軟件應(yīng)用在人們生活中各方面,人們也變得越來(lái)越重要重視聊天軟件的存在,因?yàn)榱奶燔浖诤艽蟪潭壬蠟槿嗣竦纳钷k公提供了便利,人們可以通過(guò)互聯(lián)網(wǎng)進(jìn)行信息的有效收集和整理,以及與不同地方的人交流。
目前的聊天軟件基本都是由服務(wù)器端和客戶端兩部分組成,客戶端有Web版的和本地版的,無(wú)論哪種版本,它們都需要通過(guò)與服務(wù)器端的通信來(lái)實(shí)現(xiàn)最終功能。
本文通過(guò)對(duì)服務(wù)器端的功能分析、安全性、工作流程、關(guān)鍵代碼設(shè)計(jì)等方面,來(lái)闡述安全聊天軟件服務(wù)器端的設(shè)計(jì)過(guò)程。
2 系統(tǒng)分析
服務(wù)器聊天系統(tǒng)很重要的組成部分,所以對(duì)于服務(wù)器的功能需求分析是非常重要的,正確完整的分析,是成功構(gòu)建一個(gè)聊天系統(tǒng)服務(wù)器的第一步。
能夠成功地分析好服務(wù)器的需求,對(duì)于后面設(shè)計(jì)服務(wù)器的模塊工作是不可或缺的,所以在這里,首先進(jìn)行的就是關(guān)于這個(gè)即時(shí)聊天系統(tǒng)服務(wù)器的需求分析。
2.1 登錄校驗(yàn)
輸入:來(lái)自客戶端的用戶名和密碼;
處理流程:與數(shù)據(jù)庫(kù)中的用戶名和密碼匹配,并反饋結(jié)果給客戶端;
輸出:匹配成功或失敗。
2.2 用戶注冊(cè)
輸入:來(lái)自客戶端的用戶名和密碼;
處理流程:在數(shù)據(jù)庫(kù)中寫入新用戶名和密碼,并反饋結(jié)果給客戶端;
輸出:新建成功或失敗。
2.3 消息轉(zhuǎn)發(fā)
輸入:客戶端所發(fā)送的聊天信息;
處理流程:根據(jù)所要發(fā)送到的用戶名進(jìn)行轉(zhuǎn)發(fā),用戶不在線時(shí)另作處理;
輸出:轉(zhuǎn)發(fā)信息給發(fā)往方。
2.4 文件傳輸
輸入:客戶端所發(fā)送的文件數(shù)據(jù);
處理流程:直接轉(zhuǎn)發(fā)到發(fā)往方;
輸出:轉(zhuǎn)發(fā)數(shù)據(jù)給發(fā)往方。
2.5 用戶資料維護(hù)
輸入:客戶端所發(fā)送的更新請(qǐng)求;
處理流程:按請(qǐng)求更新數(shù)據(jù)庫(kù)中對(duì)應(yīng)的數(shù)據(jù);
輸出:更新成功或失敗。
2.6 用戶列表下發(fā)
輸入:用戶登錄成功;
處理流程:當(dāng)某用戶登錄成功后,下發(fā)在線用戶列表給該用戶;
輸出:在線用戶列表。
根據(jù)服務(wù)器端的需求分析,進(jìn)行功能模塊的劃分:封包解析模塊、封包生成模塊、封包分發(fā)模塊、數(shù)據(jù)存儲(chǔ)模塊、用戶注冊(cè)模塊、用戶登錄模塊、文本信息轉(zhuǎn)發(fā)模塊、離線文本信息轉(zhuǎn)發(fā)模塊、文件傳輸模塊、用戶列表下發(fā)模塊、用戶資料模塊、超時(shí)檢測(cè)模塊,這些模塊既有獨(dú)立完成相關(guān)功能,也有相互協(xié)調(diào),合作完成最終任務(wù)。
3 安全性分析
現(xiàn)在大家使用的安全即時(shí)通訊軟件基本都是使用數(shù)據(jù)報(bào)協(xié)議UDP。UDP和傳輸控制協(xié)議TCP都是傳輸層協(xié)議,但UDP是一種面向無(wú)連接的傳輸協(xié)議,這種協(xié)議在進(jìn)行雙方數(shù)據(jù)傳輸時(shí),發(fā)送方只要知道接收方的地址和端口號(hào)就可以向接收方發(fā)送數(shù)據(jù)。這種協(xié)議帶來(lái)高速便捷的數(shù)據(jù)傳輸,但不提供數(shù)據(jù)傳送的安全保障機(jī)制,因此數(shù)據(jù)包傳輸不可靠,丟包率高。具體實(shí)現(xiàn)時(shí)要設(shè)計(jì)一種機(jī)制來(lái)對(duì)用戶傳遞的數(shù)據(jù)提供一種丟失檢測(cè)。
對(duì)于文件傳輸,如果是在同一局域網(wǎng)內(nèi),或者雙方都具有公網(wǎng)IP,只要直接建立TCP連接就可以傳文件。但是,在互聯(lián)網(wǎng)上,實(shí)際的情況比這更要復(fù)雜,客戶端有可能處于同一NAT或不同的NAT之內(nèi),客戶端之間要直接通信比較困難。在此處的文件傳輸案例中,就可以使用“TCP”打洞技術(shù),或者通過(guò)服務(wù)器中轉(zhuǎn),來(lái)穿透NAT進(jìn)行數(shù)據(jù)收發(fā)。
4 工作流程
有了完整的模塊劃分,現(xiàn)在需要的就是構(gòu)建服務(wù)器的工作流程,讓服務(wù)器運(yùn)轉(zhuǎn)起來(lái)。本聊天服務(wù)器的核心工作流程,簡(jiǎn)單地說(shuō),就是不斷把消息包分類攤派到各個(gè)不同處理模塊上的過(guò)程。
服務(wù)器在指定的端口上偵聽數(shù)據(jù)包,當(dāng)接收到數(shù)據(jù)包后,首先調(diào)用封包解析模塊對(duì)數(shù)據(jù)包進(jìn)行解析,獲取命令類型后,再根據(jù)命令類型的不同來(lái)調(diào)用不同的模塊。不同的模塊處理完成后,再調(diào)用封包生成模塊來(lái)打包結(jié)果,把處理結(jié)果發(fā)送給客戶端。
當(dāng)接收到的是登錄命令時(shí),將調(diào)用登錄管理模塊來(lái)判斷是否可以登入系統(tǒng),不管是否能登入,都把結(jié)果打包返回給客戶端。如果能成功登入,則繼續(xù)調(diào)用用戶列表下發(fā)模塊,把在線用戶列表打包發(fā)送給客戶端。
當(dāng)接收到的是注冊(cè)命令時(shí),將調(diào)用用戶注冊(cè)模塊來(lái)往系統(tǒng)中添加新用戶,注冊(cè)模塊會(huì)調(diào)用數(shù)據(jù)存儲(chǔ)模塊進(jìn)行處理,然后把結(jié)果打包返回給客戶端。
當(dāng)接收到的是資料更新命令時(shí),將調(diào)用資料管理模塊,資料管理模塊又會(huì)調(diào)用數(shù)據(jù)存儲(chǔ)模塊進(jìn)行處理,處理完成后,把結(jié)果反饋給客戶端。
當(dāng)接收到的是文本消息時(shí),將調(diào)用文本消息轉(zhuǎn)發(fā)模塊進(jìn)行處理,該模塊從解析得到的結(jié)果中,獲取所要發(fā)送往的客戶端,然后進(jìn)行轉(zhuǎn)發(fā)。如果檢測(cè)到所要發(fā)往的客戶端不在線,則轉(zhuǎn)入離線消息模塊處理。
用戶登錄后,客戶端會(huì)定時(shí)發(fā)送心跳包到服務(wù)器,服務(wù)器自動(dòng)維護(hù)此在線狀態(tài)列表,并定時(shí)執(zhí)行超時(shí)檢測(cè)模塊,把超時(shí)的用戶從在線列表中刪除。
5 關(guān)鍵代碼設(shè)計(jì)
聊天服務(wù)器的工作流程比較簡(jiǎn)單,即:收到消息→處理消息→轉(zhuǎn)發(fā)處理后的消息。聊天服務(wù)器啟動(dòng)時(shí)在特定的端口監(jiān)聽,當(dāng)有數(shù)據(jù)到達(dá)時(shí),自動(dòng)判斷消息類型,進(jìn)行不同的處理,然后根據(jù)處理結(jié)果,把它發(fā)送給客戶端。實(shí)現(xiàn)中,消息的接收和發(fā)送,以及判斷消息類型,都比較簡(jiǎn)單,工作量較大的則是處理消息的部分。因?yàn)橛泻芏嗖煌拿?,?duì)應(yīng)的,也有不同的處理過(guò)程,所以設(shè)計(jì)中,把這些處理過(guò)程分離成單獨(dú)的處理邏輯,在類中表現(xiàn)為不同的函數(shù)。本模塊的設(shè)計(jì)并不包含圖形用戶界面相關(guān)的部分,當(dāng)最終的服務(wù)器軟件需要搭配圖形界面時(shí),只需要在聊天服務(wù)器模塊中定義相關(guān)的信號(hào),并在合適的時(shí)候發(fā)出信號(hào)。圖形界面程序就可以通過(guò)聊天服務(wù)器模塊的信號(hào)和它的槽進(jìn)行連接,來(lái)實(shí)現(xiàn)顯示更新等功能。
5.1 聊天服務(wù)器端的類定義
為了利用Qt的信號(hào)和槽功能,聊天服務(wù)器類直接從QObject繼承,具體代碼如下 :
class ChatServer : public QObject
{ Q_OBJECT
public:
explicit ChatServer(QObject *parent = 0);
void start(quint16 port=4500); //啟動(dòng)服務(wù)
private:
void registerUser(const QString& id, const QString& password, const QHostAddress& addr, quint16 port);//注冊(cè)用戶
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);//轉(zhuǎn)發(fā)聊天消息
void sendFriendsList(const QHostAddress& addr, quint16 port); //發(fā)送用戶列表
void feedback(const QHostAddress& addr, quint16 port); //反饋
void logout(const QHostAddress& addr, quint16 port); //注銷
void keepAlive(const QHostAddress& addr, quint16 port); //激活
QUdpSocket *m_udpSender; //發(fā)送數(shù)據(jù)的UDP對(duì)象
QUdpSocket *m_udpReceiver; //監(jiān)聽數(shù)據(jù)的UDP對(duì)象
QHash
QHash
QHash
Storage m_storage; //數(shù)據(jù)存儲(chǔ)對(duì)象
enum {onlineTimeout = 30}; //在線超時(shí)時(shí)間
private slots:
void processPendingDatagrams(); //網(wǎng)絡(luò)數(shù)據(jù)處理
void checkTimeout(); //檢查超時(shí)狀態(tài)
};
在ChatServer類的實(shí)現(xiàn)中,需要注意名稱表、主機(jī)表以及激活狀態(tài)表的維護(hù),它們是維持服務(wù)器工作狀態(tài)的核心。為了實(shí)現(xiàn)快速查詢,這幾張表都采用Qt中的哈希表QHash進(jìn)行存儲(chǔ)。如:名稱表是用戶名到(主機(jī),端口號(hào))的映射,即通過(guò)用戶名可以查詢到對(duì)應(yīng)的主機(jī)地址和端口號(hào),在轉(zhuǎn)發(fā)消息時(shí)就要使用到名稱表。
5.2 超時(shí)檢測(cè)
超時(shí)檢測(cè)功能由定時(shí)器自動(dòng)執(zhí)行,以實(shí)現(xiàn)隔固定時(shí)間更新一次在線狀態(tài)的功能。當(dāng)?shù)竭_(dá)時(shí)間點(diǎn)時(shí),程序開始遍歷激活狀態(tài)表中的所有用戶,檢查其最后一次的心跳包時(shí)間與當(dāng)前系統(tǒng)時(shí)間的差值是否超過(guò)指定的預(yù)期,如果沒(méi)有,則表示用戶仍然正常在線,如果超時(shí),則作自動(dòng)注銷處理。具體代碼如下:
void ChatServer::checkTimeout()
{ QList
QDateTime now = QDateTime::currentDateTime(); //獲取當(dāng)前系統(tǒng)時(shí)間
for (int i = 0; i < keys.length(); ++i) //遍歷所有用戶
{ if (m_aliveTimeHash.value(keys.at(i)).secsTo(now) > onlineTimeout) //檢查用戶是否超時(shí)
{ 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); //用戶超時(shí)的時(shí)候作注銷處理
}}}
6 結(jié)束語(yǔ)
關(guān)鍵代碼介紹之后,其它功能的代碼的接口規(guī)范及實(shí)現(xiàn)也就相對(duì)容易了,這里就不再作介紹。服務(wù)器端軟件設(shè)計(jì)完成之后,配合客戶端軟件完成了消息的傳遞及轉(zhuǎn)發(fā),客戶端文件的傳輸及服務(wù)器端日志的記錄等功能。后期,還需要繼續(xù)在數(shù)據(jù)的傳輸安全性和可靠性方面做好優(yōu)化,做好客戶端其它的擴(kuò)展功能的支持,提高客戶端用戶對(duì)服務(wù)器端響應(yīng)和支持的體驗(yàn)。
參考文獻(xiàn)
[1] 丁林松,華麗琴.Qt4圖形設(shè)計(jì)與嵌入式開發(fā)[M].北京:人民郵電出版社.2009.
[2] (英)薩默菲爾德.Qt高級(jí)編程[M].北京:電子工業(yè)出版社.2011.
[3] 吳迪.零基礎(chǔ)學(xué)Qt4編程[M].北京:北京航空航天大學(xué)出版社.2010.
[4] 代勇.Visual C++網(wǎng)絡(luò)通信編程技術(shù)詳解[M].北京:機(jī)械工業(yè)出版社.2011.
[5] 行天. 聊天的危險(xiǎn)看即時(shí)通訊常見(jiàn)安全問(wèn)題[J]. 計(jì)算機(jī)與網(wǎng)絡(luò),2007,09:34-35.
[6] 李延松,余隋懷,吳博. 基于Socket的安全即時(shí)通訊軟件的設(shè)計(jì)[J]. 科學(xué)技術(shù)與工程,2007,12:2974-2977.
基金項(xiàng)目:
基于MDA技術(shù)的Web應(yīng)用平臺(tái)研究(科技創(chuàng)新)(163070054); 軟件服務(wù)外包專業(yè)實(shí)訓(xùn)體系改革(高教研究)(163070644)。
作者簡(jiǎn)介:
竇立君(1977-),男,江蘇泰州人,碩士;主要研究方向和關(guān)注領(lǐng)域:計(jì)算機(jī)應(yīng)用。