Qt第四讲 网络聊天室服务器代码

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer> //服务器类
#include <QTcpSocket> //客户端类
#include <QMessageBox>//对话框类
#include <QList>//链表容器
#include <QDebug>//信息调试类

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    QTcpServer *server; //实例化服务器指针
    QList<QTcpSocket*> socketList; //客户端容器

private slots:
    void on_sever_btn_clicked(); //按钮槽函数
    void newConnection_slot();//服务器发出信号连接的槽函数
    void readyRead_slot();//客户端发射的readyRead信号连接的槽函数

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

源文件

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    server = new QTcpServer(this);//给服务器指针实例化空间
}

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


void Widget::on_sever_btn_clicked()
{
    //监听状态
    // 函数原型 uint toUInt(bool *ok=nullptr, int base=10) const;
    quint16 port = ui->port_edit->text().toUInt();
    // 函数原型 bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
    if(server->listen(QHostAddress::Any, port)){
       QMessageBox::information(this,"提示","服务器启动成功");
    }else{
        QMessageBox::information(this,"提示","服务器启动失败");
    }
    //到此说明已经进入监听状态,连接信号与槽函数
    //客户端发请求时,服务器自动触发newConnection信号,连接此信号到槽函数
    connect(server, &QTcpServer::newConnection, this, &Widget::newConnection_slot);
}
//服务器触发newConnection信号连接的槽函数
void Widget::newConnection_slot()
{
    qDebug() <<"有新客户端连接。。。";
    //调用nextPaddingConnection函数获取最新连接客户的套接字
    //并将改套接字放入队列中
    // 函数原型 virtual QTcpSocket *nextPendingConnection();
    QTcpSocket *p_skt =  server->nextPendingConnection(); //获得套接字
    socketList.push_back(p_skt); //放入容器
    //此时客户端已经与服务器建立连接
    //如果有客户端向服务器发来数据,客户端就会自动发射一个readyRead信号
    //可以在该信号对应的槽函数获取客户端的信息
    connect(p_skt, &QTcpSocket::readyRead, this, &Widget::readyRead_slot); //客户端信号与槽函数连接
}

//客户端发射的readyRead信号连接的槽函数
void Widget::readyRead_slot()
{
    //移除无效客户端
    // 函数原型 SocketState state() const;
    // 返回值 UnconnectedState, 枚举值 0
    int i = 0;
    int j = 0;
    for(i = 0;i <socketList.count(); i++){
        if(!socketList.at(i)->state()){
            socketList.removeAt(i);// 移除
        }
    }
    //寻找有效客户端,如果有数据就读出来
    // 函数原型 qint64 bytesAvailable() const override;
    //返回值是待读取的数据的个数
    //函数原型 QByteArrarg readAll()
    //返回值是QByteArray类型的数据
    for(i = 0;i <socketList.count(); i++){
        if(socketList.at(i)->bytesAvailable()){
            //获取数据
            QByteArray msg = socketList.at(i)->readAll();
            //将数据展示到ui界面
            ui->text_list->addItem(QString::fromLocal8Bit(msg));
            //数据发给其他客户端
            for(j = 0; j < socketList.count(); j++){
                socketList.at(j)->write(msg);
            }
        }
    }

}

猜你喜欢

转载自blog.csdn.net/MaGuangming001/article/details/131987080