聊天室如何实现(怎么用实现网络聊天室的功能)

湘潭网餐饮知识
134

湘潭网小编为大家带来以下内容:

今天小编给大家分享一下怎么用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_OBJECTpublic:    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_OBJECTpublic:    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网络聊天室”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注花开半夏行业资讯频道。

君子莲(www.junzilian.com)湖南省长沙、株洲、湘潭城市宣传信息网,提供房产,人才招聘,家居装饰,教育,论坛,旅游,特产,美食,天气,娱乐,企业等资讯。



最新餐饮知识

热门推荐

为你推荐