欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

QT實(shí)現(xiàn)TCP網(wǎng)絡(luò)聊天室

 更新時(shí)間:2022年08月19日 15:47:19   作者:Soaring丶  
這篇文章主要為大家詳細(xì)介紹了QT實(shí)現(xiàn)TCP網(wǎng)絡(luò)聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了QT實(shí)現(xiàn)TCP網(wǎng)絡(luò)聊天室的具體代碼,供大家參考,具體內(nèi)容如下

服務(wù)器:

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:
? ? //創(chuàng)建服務(wù)器按鈕對應(yīng)的槽函數(shù)
? ? void on_pushButton_clicked();
? ? //響應(yīng)客戶端連接請求的槽函數(shù)
? ? void onNewConnection();
? ? //接收客戶端聊天消息的槽函數(shù)
? ? void onReadyRead();
? ? //轉(zhuǎn)發(fā)聊天消息給其它客戶端的槽函數(shù)
? ? void sendMessage(const QByteArray&);
? ? //定時(shí)器檢查客戶端套接字是否為正常連接狀態(tài)的槽函數(shù)
? ? void onTimeout(void);
private:
? ? Ui::ServerDialog *ui;
? ? QTcpServer tcpServer;//TCP服務(wù)器
? ? quint16 port;//服務(wù)器端口,quint16-->unsigned short
? ? QList<QTcpSocket*> tcpClientList;//容器:保存和客戶端通信的套接字
? ? QTimer timer;//定時(shí)器,定時(shí)檢查容器中和客戶端通信的套接字是否為正常連接狀態(tài)
};


#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;
}
//創(chuàng)建服務(wù)器按鈕對應(yīng)的槽函數(shù)
void ServerDialog::on_pushButton_clicked()
{
? ? //獲取服務(wù)器端口
? ? port = ui->lineEdit->text().toShort();
? ? //設(shè)置監(jiān)聽服務(wù)器的IP和端口
? ? //QHostAddress::Any ==> QHostAddress("0.0.0.0");
? ? if(tcpServer.listen(QHostAddress::Any,port)==false){
? ? ? ? qDebug() << "創(chuàng)建服務(wù)器失敗";
? ? ? ? return;
? ? }
? ? else{
? ? ? ? qDebug() << "創(chuàng)建服務(wù)器成功";
? ? ? ? //當(dāng)有客戶端向服務(wù)器發(fā)送連接請求時(shí),發(fā)送信號newConnection
? ? ? ? connect(&tcpServer,SIGNAL(newConnection()),
? ? ? ? ? ? ? ? this,SLOT(onNewConnection()));
? ? ? ? //禁用端口輸入和創(chuàng)建服務(wù)器按鈕
? ? ? ? ui->lineEdit->setEnabled(false);
? ? ? ? ui->pushButton->setEnabled(false);

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

? ? }
}
//響應(yīng)客戶端連接請求的槽函數(shù)
void ServerDialog::onNewConnection()
{
? ? //獲取和客戶端通信的套接字
? ? QTcpSocket* tcpClient = ?tcpServer.nextPendingConnection();
? ? //保存套接字到容器中
? ? tcpClientList.append(tcpClient);
? ? //當(dāng)客戶端給服務(wù)器發(fā)送消息時(shí),tcpClient發(fā)送信號readyRead
? ? connect(tcpClient,SIGNAL(readyRead()),
? ? ? ? ? ? this,SLOT(onReadyRead()));
}
//接收客戶端聊天消息的槽函數(shù)
void ServerDialog::onReadyRead()
{
? ? //遍歷檢查哪個(gè)客戶端有消息
? ? for(int i=0;i<tcpClientList.size();i++){
? ? ? ? //at(i):獲取容器中第i套接字(QTcpSocket*)
? ? ? ? //bytesAvailable:獲取當(dāng)前套接字等待讀取消息的字節(jié)數(shù),如果為0表示沒有消息,如果
? ? ? ? //大于0說明有消息.
? ? ? ? if(tcpClientList.at(i)->bytesAvailable()){
? ? ? ? ? ? //讀取消息并保存
? ? ? ? ? ? QByteArray buf = tcpClientList.at(i)->readAll();
? ? ? ? ? ? //顯示消息
? ? ? ? ? ? ui->listWidget->addItem(buf);
? ? ? ? ? ? //回滾到最底部(最新消息)
? ? ? ? ? ? ui->listWidget->scrollToBottom();
? ? ? ? ? ? //轉(zhuǎn)發(fā)消息給其它客戶端
? ? ? ? ? ? sendMessage(buf);
? ? ? ? }
? ? }
}
//轉(zhuǎn)發(fā)聊天消息給其它客戶端的槽函數(shù)
void ServerDialog::sendMessage(const QByteArray& msg)
{
? ? for(int i=0;i<tcpClientList.size();i++){
? ? ? ? tcpClientList.at(i)->write(msg);
? ? }
}
//定時(shí)器檢查客戶端套接字是否為正常連接狀態(tài)的槽函數(shù)
void ServerDialog::onTimeout(void)
{
? ? for(int i=0;i<tcpClientList.size();i++){
? ? ? ? //state():獲取第i個(gè)套接字的連接狀態(tà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:
? ? //發(fā)送按鈕對應(yīng)的槽函數(shù)
? ? void on_sendButton_clicked();
? ? //連接服務(wù)器按鈕對應(yīng)的槽函數(shù)
? ? void on_connectButton_clicked();
? ? //和服務(wù)器連接成功時(shí)執(zhí)行的槽函數(shù)
? ? void onConnected(void);
? ? //和服務(wù)器斷開連接時(shí)執(zhí)行的槽函數(shù)
? ? void onDisconnected(void);
? ? //接收服務(wù)器轉(zhuǎn)發(fā)聊天消息的槽函數(shù)
? ? void onReadyRead(void);
? ? //網(wǎng)絡(luò)通信異常時(shí)執(zhí)行的槽函數(shù)
? ? void onError(void);
private:
? ? Ui::ClientDialog *ui;
? ? bool status;//客戶端狀態(tài)標(biāo)記,true:在線,false:離線狀態(tài)
? ? QTcpSocket tcpSocket;//和服務(wù)器通信的tcp套接字
? ? QHostAddress serverIp;//服務(wù)器地址
? ? quint16 serverPort;//服務(wù)器端口
? ? 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;
? ? //和服務(wù)器連接成功時(shí),tcpSocket發(fā)送信號:connected
? ? connect(&tcpSocket,SIGNAL(connected()),
? ? ? ? ? ? this,SLOT(onConnected()));
? ? //和服務(wù)器斷開連接時(shí),tcpSocket發(fā)送信號:disconnected
? ? connect(&tcpSocket,SIGNAL(disconnected()),
? ? ? ? ? ? this,SLOT(onDisconnected()));
? ? //收到聊天消息時(shí),tcpSocket發(fā)送信號:readyRead
? ? connect(&tcpSocket,SIGNAL(readyRead()),
? ? ? ? ? ? this,SLOT(onReadyRead()));
? ? //網(wǎng)絡(luò)通信異常時(shí),tcpSocket發(fā)送信號:error
? ? connect(&tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),
? ? ? ? ? ? this,SLOT(onError()));
}

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

最終實(shí)現(xiàn)效果:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論