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

溫馨提示×

溫馨提示×

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

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

怎么用QT實現TCP網絡聊天室

發布時間:2022-08-25 11:26:07 來源:億速云 閱讀:318 作者:iii 欄目:開發技術

今天小編給大家分享一下怎么用QT實現TCP網絡聊天室的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

服務器

serverdialog.h

#ifndef SERVERDIALOG_H
#define SERVERDIALOG_H

#include <QDialog>
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
#include <QTimer>

namespace Ui {
class ServerDialog;
}

class ServerDialog : public QDialog
{
    Q_OBJECT

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

private slots:
    //創建服務器按鈕對應的槽函數
    void on_pushButton_clicked();
    //響應客戶端連接請求的槽函數
    void onNewConnection();
    //接收客戶端聊天消息的槽函數
    void onReadyRead();
    //轉發聊天消息給其它客戶端的槽函數
    void sendMessage(const QByteArray&);
    //定時器檢查客戶端套接字是否為正常連接狀態的槽函數
    void onTimeout(void);
private:
    Ui::ServerDialog *ui;
    QTcpServer tcpServer;//TCP服務器
    quint16 port;//服務器端口,quint16-->unsigned short
    QList<QTcpSocket*> tcpClientList;//容器:保存和客戶端通信的套接字
    QTimer timer;//定時器,定時檢查容器中和客戶端通信的套接字是否為正常連接狀態
};


#endif // SERVERDIALOG_H

serverdialog.cpp

#include "serverdialog.h"
#include "ui_serverdialog.h"

ServerDialog::ServerDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ServerDialog)
{
    ui->setupUi(this);
}

ServerDialog::~ServerDialog()
{
    delete ui;
}
//創建服務器按鈕對應的槽函數
void ServerDialog::on_pushButton_clicked()
{
    //獲取服務器端口
    port = ui->lineEdit->text().toShort();
    //設置監聽服務器的IP和端口
    //QHostAddress::Any ==> QHostAddress("0.0.0.0");
    if(tcpServer.listen(QHostAddress::Any,port)==false){
        qDebug() << "創建服務器失敗";
        return;
    }
    else{
        qDebug() << "創建服務器成功";
        //當有客戶端向服務器發送連接請求時,發送信號newConnection
        connect(&tcpServer,SIGNAL(newConnection()),
                this,SLOT(onNewConnection()));
        //禁用端口輸入和創建服務器按鈕
        ui->lineEdit->setEnabled(false);
        ui->pushButton->setEnabled(false);

        //定時器到時發送信號:timeout
        connect(&timer,SIGNAL(timeout()),this,SLOT(onTimeout()));
        //開啟定時器,每隔3秒檢查一次
        timer.start(3000);

    }
}
//響應客戶端連接請求的槽函數
void ServerDialog::onNewConnection()
{
    //獲取和客戶端通信的套接字
    QTcpSocket* tcpClient =  tcpServer.nextPendingConnection();
    //保存套接字到容器中
    tcpClientList.append(tcpClient);
    //當客戶端給服務器發送消息時,tcpClient發送信號readyRead
    connect(tcpClient,SIGNAL(readyRead()),
            this,SLOT(onReadyRead()));
}
//接收客戶端聊天消息的槽函數
void ServerDialog::onReadyRead()
{
    //遍歷檢查哪個客戶端有消息
    for(int i=0;i<tcpClientList.size();i++){
        //at(i):獲取容器中第i套接字(QTcpSocket*)
        //bytesAvailable:獲取當前套接字等待讀取消息的字節數,如果為0表示沒有消息,如果
        //大于0說明有消息.
        if(tcpClientList.at(i)->bytesAvailable()){
            //讀取消息并保存
            QByteArray buf = tcpClientList.at(i)->readAll();
            //顯示消息
            ui->listWidget->addItem(buf);
            //回滾到最底部(最新消息)
            ui->listWidget->scrollToBottom();
            //轉發消息給其它客戶端
            sendMessage(buf);
        }
    }
}
//轉發聊天消息給其它客戶端的槽函數
void ServerDialog::sendMessage(const QByteArray& msg)
{
    for(int i=0;i<tcpClientList.size();i++){
        tcpClientList.at(i)->write(msg);
    }
}
//定時器檢查客戶端套接字是否為正常連接狀態的槽函數
void ServerDialog::onTimeout(void)
{
    for(int i=0;i<tcpClientList.size();i++){
        //state():獲取第i個套接字的連接狀態
        //UnconnectedState:表示未連接(斷開連接)
        if(tcpClientList.at(i)->state() ==
                QAbstractSocket::UnconnectedState){
            //從容器中將斷開連接的套接字移除
            tcpClientList.removeAt(i);
            --i;
        }
    }
}

main.cpp

#include "serverdialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ServerDialog w;
    w.show();

    return a.exec();
}

客戶端:

clientdialog:

#ifndef CLIENTDIALOG_H
#define CLIENTDIALOG_H

#include <QDialog>
//QT += network
#include <QTcpSocket>
#include <QHostAddress>
#include <QMessageBox>

namespace Ui {
class ClientDialog;
}

class ClientDialog : public QDialog
{
    Q_OBJECT

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

private slots:
    //發送按鈕對應的槽函數
    void on_sendButton_clicked();
    //連接服務器按鈕對應的槽函數
    void on_connectButton_clicked();
    //和服務器連接成功時執行的槽函數
    void onConnected(void);
    //和服務器斷開連接時執行的槽函數
    void onDisconnected(void);
    //接收服務器轉發聊天消息的槽函數
    void onReadyRead(void);
    //網絡通信異常時執行的槽函數
    void onError(void);
private:
    Ui::ClientDialog *ui;
    bool status;//客戶端狀態標記,true:在線,false:離線狀態
    QTcpSocket tcpSocket;//和服務器通信的tcp套接字
    QHostAddress serverIp;//服務器地址
    quint16 serverPort;//服務器端口
    QString username;//聊天室昵稱
};

#endif // CLIENTDIALOG_H

clientdialog.cpp

#include "clientdialog.h"
#include "ui_clientdialog.h"

ClientDialog::ClientDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ClientDialog)
{
    ui->setupUi(this);
    status = false;
    //和服務器連接成功時,tcpSocket發送信號:connected
    connect(&tcpSocket,SIGNAL(connected()),
            this,SLOT(onConnected()));
    //和服務器斷開連接時,tcpSocket發送信號:disconnected
    connect(&tcpSocket,SIGNAL(disconnected()),
            this,SLOT(onDisconnected()));
    //收到聊天消息時,tcpSocket發送信號:readyRead
    connect(&tcpSocket,SIGNAL(readyRead()),
            this,SLOT(onReadyRead()));
    //網絡通信異常時,tcpSocket發送信號:error
    connect(&tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),
            this,SLOT(onError()));
}

ClientDialog::~ClientDialog()
{
    delete ui;
}
//發送按鈕對應的槽函數
void ClientDialog::on_sendButton_clicked()
{
    //獲取用戶輸入的消息
    QString msg = ui->messageEdit->text();
    if(msg == ""){
        return;
    }
    msg = username + ":" + msg;
    //發送消息
    tcpSocket.write(msg.toUtf8());
    //清空已輸入的消息
    ui->messageEdit->clear();
}
//連接服務器按鈕對應的槽函數
void ClientDialog::on_connectButton_clicked()
{
    if(status == false){//如果當前是離線狀態,則連接服務器
        //獲取服務器IP
        if(serverIp.setAddress(ui->serverIpEdit->text())==false){
            //critical():表示錯誤的消息提示框
            QMessageBox::critical(this,"Error","IP地址錯誤");
            return;
        }
        //獲取服務器端口
        serverPort = ui->serverportEdit->text().toShort();
        if(serverPort < 1024){
            QMessageBox::critical(this,"Error","端口格式錯誤");
            return;
        }
        //獲取聊天室昵稱
        username = ui->usernameEdit->text();
        if(username == ""){
            QMessageBox::critical(this,"Error","聊天室昵稱不能為空");
            return;
        }
        //向服務器發送連接請求:
        //如果成功,發送信號:connected;
        //如果失敗,發送信號:error
        tcpSocket.connectToHost(serverIp,serverPort);
    }
    else{//如果當前是在線狀態,則斷開和服務器連接
        //向服務器發送離開聊天室的消息
        QString msg = username + ":離開了聊天室";
        //toUtf8():將QString(unicode)轉換QByteArray(utf-8)
        tcpSocket.write(msg.toUtf8());
        //斷開連接
        //斷開后發送信號:disconnected
        tcpSocket.disconnectFromHost();
    }
}
//和服務器連接成功時執行的槽函數
void ClientDialog::onConnected(void)
{
    status = true;//設置狀態標記:在線
    ui->sendButton->setEnabled(true);//恢復"發送"按鈕為正常可用狀態
    ui->serverIpEdit->setEnabled(false);//禁用ip輸入
    ui->serverportEdit->setEnabled(false);//禁用端口輸入
    ui->usernameEdit->setEnabled(false);//禁用昵稱輸入
    ui->connectButton->setText("離開聊天室");//修改連接服務器按鈕文本
    //向服務器發送進入聊天室提示消息
    QString msg = username + ":進入了聊天室";
    //toUtf8():將QString(unicode)轉換QByteArray(utf-8)
    tcpSocket.write(msg.toUtf8());
}
//和服務器斷開連接時執行的槽函數
void ClientDialog::onDisconnected(void)
{
    status = false;//設置離線狀態
    ui->sendButton->setEnabled(false);//禁用"發送"按鈕
    ui->serverIpEdit->setEnabled(true);//恢復ip輸入
    ui->serverportEdit->setEnabled(true);//恢復端口輸入
    ui->usernameEdit->setEnabled(true);//恢復昵稱輸入
    ui->connectButton->setText("連接服務器");//修改離開聊天室按鈕文本
}
//接收服務器轉發聊天消息的槽函數
void ClientDialog::onReadyRead(void)
{
    //bytesAvailable():獲取等待讀取消息的字節數
    if(tcpSocket.bytesAvailable()){
        //讀取消息
        QByteArray buf = tcpSocket.readAll();
        //顯示消息到界面
        ui->listWidget->addItem(buf);
        ui->listWidget->scrollToBottom();
    }
}
//網絡通信異常時執行的槽函數
void ClientDialog::onError(void)
{
    //errorString():獲取網絡通信異常原因的字符串
    QMessageBox::critical(this,"Error",tcpSocket.errorString());
}

main.cpp

#include "clientdialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ClientDialog w;
    w.show();

    return a.exec();
}

最終實現效果:

怎么用QT實現TCP網絡聊天室

以上就是“怎么用QT實現TCP網絡聊天室”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

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

AI

黑山县| 花垣县| 玉山县| 吉首市| 南岸区| 永德县| 吉水县| 新源县| 来宾市| 五家渠市| 长乐市| 周至县| 洪泽县| 长武县| 宁河县| 南丹县| 合江县| 琼海市| 兴义市| 江津市| 沙坪坝区| 清镇市| 龙里县| 儋州市| 沭阳县| 扶沟县| 巢湖市| 太谷县| 深水埗区| 榆林市| 南安市| 山东| 绥阳县| 岳西县| 新晃| 莱芜市| 北辰区| 长垣县| 乐至县| 太康县| 梅州市|