嵌入式:QT Day4

一、手动完成服务器的实现,并注释具体步骤

嵌入式:QT Day4_第1张图片

嵌入式:QT Day4_第2张图片

源码:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include                //服务器类
#include                //客户端类
#include               //对话框类
#include                     //链表容器
#include                    //信息调试类

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void newConnnecttion_slot();              //自定义槽函数,用来处理有客户端发送连接请求后,服务器自动发送的newConnecttion信号
    void readyRead_slot();                    //自定义槽函数,用来处理客户端要向客户端发送信息时,客户端自动发送的readyRead信号

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;

    //定义服务器指针
    QTcpServer *server;
    //定义存储客户端套接字容器
    QList sockList;

};
#endif // WIDGET_H

widget.cpp

#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_pushButton_clicked()
{
    //将行编辑器的内容赋值到port中
    quint16 port = ui->lineEdit->text().toUInt();

    //监听
    if(server->listen(QHostAddress::Any, port)){
        QMessageBox::information(this, "连接提示", "客户端连接成功!");
    }else{
        QMessageBox::information(this, "连接提示", "客户端连接失败!");
    }

    //此时服务器已经处于监听状态,如果有客户端发送连接请求,那么该服务器会自动发送newConnnecttion信号
    //我们可以将该信号连接到自定义的槽函数中,处理新套接字
    connect(server, &QTcpServer::newConnection, this, &Widget::newConnnecttion_slot);

}

void Widget::newConnnecttion_slot()
{
    //保存服务器接收到的客户端套接字指针
    QTcpSocket *s = server->nextPendingConnection();

    //将该套接字指针放到容器中
    sockList.push_back(s);

    //此时服务器与客户端已建立连接
    //如果客户端要向服务器发送信息,那么会发送一个readyRead信号
    //此时需要将该信号与自定义槽函数连接,读取客户端数据
    connect(s, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);

}

void Widget::readyRead_slot(){
    //移除无效客户端
    for(int i = 0; i < sockList.count(); i++){      //sockList.count()  表示存储客户端套接字的容器内元素个数
        if(sockList.at(i)->state() == 0){           //state表示客户端的状态,是一个枚举值,=0表示该客户端已断开连接
            sockList.removeAt(i);                   //移除该客户端
        }
    }

    //遍历客户端容器,判断是哪个客户端有数据要读
    for(int i = 0; i < sockList.count(); i++){
        if(sockList.at(i)->bytesAvailable() != 0){      //表示该客户端有数据要读
            //读取该客户端发送的全部信息
            QByteArray msg = sockList.at(i)->readAll();

            //将数据展示到ui界面
            ui->listWidget->addItem(QString::fromLocal8Bit(msg));

            //将该消息发送给所有客户端
            for(int i = 0; i < sockList.count(); i++){
                sockList.at(i)->write(msg);
            }
        }
    }
}

main.cpp

#include "widget.h"

#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

二、思维导图

你可能感兴趣的:(qt,开发语言)