1. 程式人生 > >Qt實現的區域網通訊軟體(仿QQ版本)

Qt實現的區域網通訊軟體(仿QQ版本)

Qt5實現的區域網通訊工具,支援公網。類似軟體百度一大把,但是還是想整理一份屬於自己的專屬QQ。支援跨平臺。

1目的       

   本文主要介紹利用Qt實現區域網通訊的主要實現流程和一些技術知識點的設計說明。

2總體設計

2.1 功能特點

這款區域網通訊軟體是基於Qt的實現的C/S架構通訊,通訊功能全部採用QTcpSocket完成的。該軟體分為2部分,一部分是服務端,一部分是客戶端。

訊息通訊採用QJsonValue的格式進行封裝,方便封裝和解析。

2.2 模組結構

    整個設計可以大致分為服務端、客戶端,服務端功能相對比較單一,僅僅做了客戶端的訊息管理和轉發等。資料庫讀寫等。客戶端相對較為豐富。包括好友管理、群組管理、tcp訊息管理,資料庫管理,

    整個專案設計的功能的設計流程圖大致如下所示:

圖2-1

2.3 開發環境

本專案的採用Qt進行設計開發,Qt版本為5.7.0,在後續程式碼維護和修改的時候建議使用該版本或更高的版本。

3模組說明     

本設計中主要使用4個大類,一個QTcpServer,另外一個是QTcpSocket,主要是用於通訊的,但是他們通訊的時候採用了QJsonValue的資料格式進行互動,下面針對這個幾個主要的模組進行簡單介紹下。最後就是資料庫QDataBase

3.1 QTcpServer類

   本設計中伺服器使用的就是QTcpServer,我們在使用他的時候只需要知道的一個訊號就行了,就是有新的tcp連結上來的額時候,可以及時通知我,然後我這邊進行客戶端的連結處理。如下:

  m_tcpServer = new QTcpServer(this);
  connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(SltNewConnection()));

當有新的客戶端連結上來,我們只需要在這個槽函式中進行處理就行了。

3.2 QTcpSocket類

該類為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()));

3.3 QJsonValue類

該類為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);;
}

3.4 QSqlDataBase類

服務端:

建立使用者資料庫表

query.exec("CREATE TABLE USERINFO (id INT PRIMARY KEY, name varchar(20), "
               "passwd varchar(20), status INT, groupId INT, lasttime DATETIME);");
Id
Name
Passwd
Status
groupId
lasttime
唯一標識
使用者名稱
使用者密碼
線上狀態
群組id
最後時間

表3-4-1 使用者資料庫表設計

    query.exec("CREATE TABLE GROUPINFO (id INT PRIMARY KEY, groupId INT, name varchar(20), "
               "userId INT, identity INT)");
Id
groupId
name
userId
identity
唯一標識
群組id
群名字
使用者id
使用者身份

客戶端:

    // 建立歷史聊天表
    query.exec("CREATE TABLE MSGINFO (id INT PRIMARY KEY, userId INT,"
                          "type INT, direction INT, content varchar(500))");
Id
userId 
type 
direction 
content 
唯一標識
使用者id
訊息型別
聊天方向
訊息內容
    // 建立我的好友表
    query.exec("CREATE TABLE FRIEND (id INT PRIMARY KEY, name varchar(50))");
Id
name 
唯一標識(好友id)
好友名字
    // 建立群組表
    query.exec("CREATE TABLE MYGROUP (id INT PRIMARY KEY, name varchar(50))");
Id
name 
唯一標識(好友id)
好友名字

表3-4-5使用者資料庫表設計

4 介面設計

4.1 服務端介面設計

圖4-1 服務端介面

4.2 客戶端介面設計

客戶端介面相對比較複雜,介面風格仿照QQ的主面板設計,分為好友管列表,群組管理列表。

 

圖4-2 客戶端主介面

圖4-3 私聊視窗

聊天介面採用QWidget的繪製,模仿QQ聊天氣泡進行設計的,目前支援功能檔案傳輸功能(伺服器轉發,先將要傳送的檔案傳給伺服器,然後通過伺服器將該檔案訊息傳送至對端客戶,對端客戶可以選擇下載檔案,也可以選擇不下載檔案)。

檔案傳送機制:採用檔案分片的方式將整個檔案拆分成byte進行傳送,每次傳送50個byte,在區域網可以達到10M/S的傳輸速率。

圖4-4群組聊天

群組聊天機制:當該群組裡面的某個好友主動發起會話時,伺服器會自動吧該訊息轉發給其他線上的組成員,並簡單的封裝下,是誰傳送的訊息。以此進行區分。

4.3 客戶端介面設計


圖4-5 登陸介面

在本設計中,添加了一個使用者登陸的功能,因為走tcp流程,需要進行使用者認證,點選登陸時,通過tcp傳送認證訊息至服務端,伺服器查詢伺服器的資料庫檔案,如果查詢到,返回JSON格式的資料給該客戶端,並通過認證,可登陸主介面,否則如上彈出登陸校驗失敗的錯誤提示框。

使用者註冊:方法也是通過tcp傳送註冊訊息至服務端,並獲取返回的json資料。

4.4 其他設計

1、資料庫聊天記錄儲存,當第一次載入該訊息框時,會自動載入最近10條記錄,並顯示,如果想要獲取全部的聊天記錄,可直接點選聊天視窗上的歷史記錄按鈕即可。

2、好友管理,目前只新增使用者新增功能,使用者刪除功能沒做,可以自行新增。

3、群組管理,與好友管理方法類似,刪除功能為做。

4結語

好友管理類使用的QListWidget進行封裝處理的,理聊天的氣泡介面也是通過QPainter進行繪製,自己管理的列表類,支援滑鼠滾輪滑動。