中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Qt實現網絡聊天室的方法

發布時間:2021-06-23 13:53:38 來源:億速云 閱讀:356 作者:chen 欄目:開發技術

本篇內容主要講解“Qt實現網絡聊天室的方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Qt實現網絡聊天室的方法”吧!

目錄
  • 1. 效果演示

  • 2. 預備知識

    • 2.1 QTcpServer

    • 2.2 QTcpServer信號

    • 2.3 QTcpSocket

    • 2.4 QTcpSocket信號

  • 3. 通信流程

1. 效果演示

客戶端

Qt實現網絡聊天室的方法

服務器

Qt實現網絡聊天室的方法

連接成功之后

Qt實現網絡聊天室的方法

2. 預備知識

在Qt中,實現網絡編程的方式比用C++或C實現要方便簡單許多,因為Qt已經替我們封裝好了,我們會使用就可以了,然后大家還需要了解Qt 的信號槽機制,可以參考我這篇文章,Qt信號槽

2.1 QTcpServer

QTcpServer 類用于監聽客戶端連接以及和客戶端建立連接,在使用之前先介紹一下這個類提供的一些常用 API 函數:

構造函數

QTcpServer::QTcpServer(QObject *parent = Q_NULLPTR);

給監聽的套接字設置監聽

bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
// 判斷當前對象是否在監聽, 是返回true,沒有監聽返回false
bool QTcpServer::isListening() const;
// 如果當前對象正在監聽返回監聽的服務器地址信息, 否則返回 QHostAddress::Null
QHostAddress QTcpServer::serverAddress() const;
// 如果服務器正在監聽連接,則返回服務器的端口; 否則返回0
quint16 QTcpServer::serverPort() const

參數:
address:通過類 QHostAddress 可以封裝 IPv4、IPv6 格式的 IP 地址,QHostAddress::Any 表示自動綁定
port:如果指定為 0 表示隨機綁定一個可用端口。
返回值:綁定成功返回 true,失敗返回 false

得到和客戶端建立連接之后用于通信的 QTcpSocket 套接字對象,它是 QTcpServer 的一個子對象,當 QTcpServer 對象析構的時候會自動析構這個子對象,當然也可自己手動析構,建議用完之后自己手動析構這個通信的 QTcpSocket 對象。

QTcpSocket *QTcpServer::nextPendingConnection();

阻塞等待客戶端發起的連接請求,不推薦在單線程程序中使用,建議使用非阻塞方式處理新連接,即使用信號 newConnection() 。

bool QTcpServer::waitForNewConnection(int msec = 0, bool *timedOut = Q_NULLPTR);

參數:
msec:指定阻塞的最大時長,單位為毫秒(ms)
timeout:傳出參數,如果操作超時 timeout 為 true,沒有超時 timeout 為 false

2.2 QTcpServer信號

當接受新連接導致錯誤時,將發射如下信號。socketError 參數描述了發生的錯誤相關的信息

[signal] void QTcpServer::acceptError(QAbstractSocket::SocketError socketError);

每次有新連接可用時都會發出 newConnection () 信號。

[signal] void QTcpServer::newConnection();

2.3 QTcpSocket

QTcpSocket 是一個套接字通信類,不管是客戶端還是服務器端都需要使用。在 Qt 中發送和接收數據也屬于 IO 操作(網絡 IO)

構造函數

QTcpSocket::QTcpSocket(QObject *parent = Q_NULLPTR);

連接服務器,需要指定服務器端綁定的IP和端口信息。

[virtual] void QAbstractSocket::connectToHost(const QString &hostName, quint16 port, OpenMode openMode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);

[virtual] void QAbstractSocket::connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite);

在 Qt 中不管調用讀操作函數接收數據,還是調用寫函數發送數據,操作的對象都是本地的由 Qt 框架維護的一塊內存。因此,調用了發送函數數據不一定會馬上被發送到網絡中,調用了接收函數也不是直接從網絡中接收數據,關于底層的相關操作是不需要使用者來維護的。

接收數據

// 指定可接收的最大字節數 maxSize 的數據到指針 data 指向的內存中
qint64 QIODevice::read(char *data, qint64 maxSize);
// 指定可接收的最大字節數 maxSize,返回接收的字符串
QByteArray QIODevice::read(qint64 maxSize);
// 將當前可用操作數據全部讀出,通過返回值返回讀出的字符串
QByteArray QIODevice::readAll();

2.4 QTcpSocket信號

在使用 QTcpSocket 進行套接字通信的過程中,如果該類對象發射出 readyRead() 信號,說明對端發送的數據達到了,之后就可以調用 read 函數接收數據了。

[signal] void QIODevice::readyRead();

調用 connectToHost() 函數并成功建立連接之后發出 connected() 信號。
在套接字斷開連接時發出 disconnected() 信號。

調用 connectToHost() 函數并成功建立連接之后發出 connected() 信號。
[signal] void QAbstractSocket::disconnected();

3. 通信流程

3.1 服務器端

  • 創建套接字服務器 QTcpServer 對象

  • 通過 QTcpServer 對象設置監聽,即:QTcpServer::listen()

  • 基于 QTcpServer::newConnection() 信號檢測是否有新的客戶端連接

  • 如果有新的客戶端連接調用 QTcpSocket *QTcpServer::nextPendingConnection() 得到通信的套接字對象

  • 使用通信的套接字對象 QTcpSocket 和客戶端進行通信

頭文件

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_startServer_clicked();

    void on_sendMsg_clicked();

private:
    Ui::MainWindow *ui;
    QTcpServer* m_server;
    QTcpSocket* m_tcp;
};

源文件

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle("TCP - 服務器");
    // 創建 QTcpServer 對象
    m_server = new QTcpServer(this);
    // 檢測是否有新的客戶端連接
    connect(m_server, &QTcpServer::newConnection, this, [=]()
    {
        m_tcp = m_server->nextPendingConnection();
        ui->record->append("成功和客戶端建立了新的連接...");
        m_status->setPixmap(QPixmap(":/connect.png").scaled(20, 20));
        // 檢測是否有客戶端數據
        connect(m_tcp, &QTcpSocket::readyRead, this, [=]()
        {
            // 接收數據
            QString recvMsg = m_tcp->readAll();
            ui->record->append("客戶端Say: " + recvMsg);
        });
        // 客戶端斷開了連接
        connect(m_tcp, &QTcpSocket::disconnected, this, [=]()
        {
            ui->record->append("客戶端已經斷開了連接...");
            m_tcp->deleteLater();
            m_status->setPixmap(QPixmap(":/disconnect.png").scaled(20, 20));
        });
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 啟動服務器端的服務按鈕
void MainWindow::on_startServer_clicked()
{
    unsigned short port = ui->port->text().toInt();
    // 設置服務器監聽
    m_server->listen(QHostAddress::Any, port);
    ui->startServer->setEnabled(false);
}

// 點擊發送數據按鈕
void MainWindow::on_sendMsg_clicked()
{
    QString sendMsg = ui->msg->toPlainText();
    m_tcp->write(sendMsg.toUtf8());
    ui->record->append("服務器Say: " + sendMsg);
    ui->msg->clear();

3.2 客戶端

通信流程

  • 創建通信的套接字類 QTcpSocket 對象

  • 使用服務器端綁定的 IP 和端口連接服務器 QAbstractSocket::connectToHost()

  • 使用 QTcpSocket 對象和服務器進行通信

頭文件

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_connectServer_clicked();

    void on_sendMsg_clicked();

    void on_disconnect_clicked();

private:
    Ui::MainWindow *ui;
    QTcpSocket* m_tcp;
};

源文件

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle("TCP - 客戶端");

    // 創建通信的套接字對象
    m_tcp = new QTcpSocket(this);
    // 檢測服務器是否回復了數據
    connect(m_tcp, &QTcpSocket::readyRead, [=]()
    {
        // 接收服務器發送的數據
        QByteArray recvMsg = m_tcp->readAll();
        ui->record->append("服務器Say: " + recvMsg);
    });
        
    // 檢測是否和服務器是否連接成功了
    connect(m_tcp, &QTcpSocket::connected, this, [=]()
    {
        ui->record->append("恭喜, 連接服務器成功!!!");
        m_status->setPixmap(QPixmap(":/connect.png").scaled(20, 20));
    });
        
    // 檢測服務器是否和客戶端斷開了連接
    connect(m_tcp, &QTcpSocket::disconnected, this, [=]()
    {
        ui->record->append("服務器已經斷開了連接, ...");
        ui->connectServer->setEnabled(true);
        ui->disconnect->setEnabled(false);
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 連接服務器按鈕按下之后的處理動作
void MainWindow::on_connectServer_clicked()
{
    QString ip = ui->ip->text();
    unsigned short port = ui->port->text().toInt();
    // 連接服務器
    m_tcp->connectToHost(QHostAddress(ip), port);
    ui->connectServer->setEnabled(false);
    ui->disconnect->setEnabled(true);
}

// 發送數據按鈕按下之后的處理動作
void MainWindow::on_sendMsg_clicked()
{
    QString sendMsg = ui->msg->toPlainText();
    m_tcp->write(sendMsg.toUtf8());
    ui->record->append("客戶端Say: " + sendMsg);
    ui->msg->clear();
}

// 斷開連接按鈕被按下之后的處理動作
void MainWindow::on_disconnect_clicked()
{
    m_tcp->close();
    ui->connectServer->setEnabled(true);
    ui->disconnect->setEnabled(false);
}

到此,相信大家對“Qt實現網絡聊天室的方法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

qt
AI

苗栗县| 阆中市| 吴川市| 邢台县| 台安县| 永仁县| 眉山市| 防城港市| 理塘县| 青冈县| 汪清县| 马公市| 巨野县| 屏东市| 台州市| 仁怀市| 新闻| 海安县| 郑州市| 潮安县| 汕尾市| 丰顺县| 吉水县| 成都市| 宜宾市| 来安县| 高清| 铜川市| 阆中市| 安远县| 开原市| 威信县| 高要市| 宜兰市| 东莞市| 方山县| 永川市| 偏关县| 通辽市| 光泽县| 贵港市|