首页
社区
课程
招聘
[原创]QT 实现MQTT 协议通信
2020-5-31 16:46 8329

[原创]QT 实现MQTT 协议通信

2020-5-31 16:46
8329

MQTT 接收

链接

 

最近作业要求,研究了一下MQTT(只能说是简单的实现了一下),顺便使用QT写了一个测试工具
下面是对每一个功能的详解

1、EMQ QMQTT

QMQTT 是QT 提供的MQTT 依赖,需要进行编译后,加载lib文件(有些说的是.a 文件,但我编译完成后就只有lib 文件,尴尴尬尬)。
教程转:链接

2、界面设计

在这里插入图片描述

3、代码

3.1 初始化

  1. 创建对象,声明方法
private:
    Ui::MainWindow *ui;
    QMQTT::Client * client;
private slots:
    void onMQTT_Received(const QMQTT::Message &message);
    void onMQTT_subscribed(const QString& topic);
  1. 构造器初始化
client = new Client();

    connect(client,SIGNAL(received(const QMQTT::Message&)),this,SLOT(onMQTT_Received(const QMQTT::Message&)));
    connect(client,SIGNAL(subscribed(const QString&)),this,SLOT(onMQTT_subscribed(const QString&)));

对应方法实现

void MainWindow::onMQTT_Received(const QMQTT::Message &message)
{
    // 接受到服务器消息时的处理
    QString strPaylaod = message.payload();
    //QMessageBox::warning(this,"payload",strPaylaod,QMessageBox::Yes,QMessageBox::No);
    QString strLine = ui->textBrowser_msg->toPlainText();

    QDateTime dt = QDateTime::currentDateTime();
    QString strDate = dt.toString(Qt::SystemLocaleLongDate);//日期格式自定义
    strLine += "\n";
    strLine += strDate;
    strLine += "\n";
    strLine += strPaylaod;

    ui->textBrowser_msg->setText(strLine);

}
void MainWindow::onMQTT_subscribed(const QString &topic)
{

    // 订阅成功后的处理
    qDebug() << topic;
     QMessageBox::warning(this,"订阅成功",topic,QMessageBox::Yes);

}

3.2 连接服务器

void MainWindow::on_pushButton_conn_clicked()
{
    // 取出ip,端口等数据
    QHostAddress host(QString(ui->lineEdit_ip->text()));
    quint16 port = ui->spinBox->value();
    quint16 QosNum = ui->spinBox_QoS->value();
    QString cId = ui->lineEdit_clientId->text();
    QString username = ui->lineEdit_username->text();
    QString psword = ui->lineEdit_psword->text();
    QString ip = ui->lineEdit_ip->text();

    if(cId == "" || username == "" || psword == "" || ip == "")
    {
        QMessageBox::warning(this,"提示","请将信息输入完整",QMessageBox::Yes);
        return;
    }

    // 对客户端对象设置属性
    client->setHost(host);
    client->setPort(port);
    client->setWillQos(QosNum);
    client->setClientId(cId);

    // 建立连接
    client->connectToHost();


}

3.3 发送消息(这里有一些问题,不知道是我那写错了,希望大佬帮忙改改)

问题:每次发送消息后,断开连接才另一端才能接受到,尴尴尬尬

void MainWindow::on_pushButton_send_clicked()
{
    // 发送消息
   /* client->setWillMessage("111111");
    client->disconnectFromHost();
    client->connectToHost();*/


    // 测试代码
    client->disconnectFromHost();
    QHostAddress host(QString(ui->lineEdit_ip->text()));
    quint16 port = ui->spinBox->value();
    quint16 QosNum = ui->spinBox_QoS->value();
    QString cId = ui->lineEdit_clientId->text();
    QString username = ui->lineEdit_username->text();
    QString psword = ui->lineEdit_psword->text();
    QString ip = ui->lineEdit_ip->text();

    if(cId == "" || username == "" || psword == "" || ip == "")
    {
        QMessageBox::warning(this,"提示","请将信息输入完整",QMessageBox::Yes);
        return;
    }

    client->setHost(host);
    client->setPort(port);
    client->setWillQos(QosNum);
    client->setClientId(cId);
    client->connectToHost();
    QByteArray qbyte = ui->lineEdit_sendMsg->text().toUtf8();
    client->setWillMessage(qbyte);
    client->disconnectFromHost();

    // 恢复连接
    client->connectToHost();

}

完整代码

UI
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>380</width>
    <height>501</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QLineEdit" name="lineEdit_clientId">
    <property name="geometry">
     <rect>
      <x>60</x>
      <y>150</y>
      <width>133</width>
      <height>26</height>
     </rect>
    </property>
   </widget>
   <widget class="QLabel" name="label_7">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>150</y>
      <width>48</width>
      <height>26</height>
     </rect>
    </property>
    <property name="text">
     <string>CID:</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="lineEdit_sendMsg">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>190</y>
      <width>261</width>
      <height>31</height>
     </rect>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton_send">
    <property name="geometry">
     <rect>
      <x>280</x>
      <y>190</y>
      <width>81</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>发送</string>
    </property>
   </widget>
   <widget class="QSplitter" name="splitter_2">
    <property name="geometry">
     <rect>
      <x>60</x>
      <y>20</y>
      <width>133</width>
      <height>121</height>
     </rect>
    </property>
    <property name="orientation">
     <enum>Qt::Vertical</enum>
    </property>
    <widget class="QSplitter" name="splitter_8">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <widget class="QSplitter" name="splitter_9">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <widget class="QLineEdit" name="lineEdit_username">
       <property name="echoMode">
        <enum>QLineEdit::Normal</enum>
       </property>
      </widget>
      <widget class="QLineEdit" name="lineEdit_psword">
       <property name="echoMode">
        <enum>QLineEdit::Password</enum>
       </property>
      </widget>
      <widget class="QLineEdit" name="lineEdit_ip"/>
      <widget class="QLineEdit" name="lineEdit_dy"/>
     </widget>
    </widget>
   </widget>
   <widget class="QSplitter" name="splitter_3">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>20</y>
      <width>48</width>
      <height>121</height>
     </rect>
    </property>
    <property name="orientation">
     <enum>Qt::Vertical</enum>
    </property>
    <widget class="QLabel" name="label">
     <property name="text">
      <string>用户名:</string>
     </property>
    </widget>
    <widget class="QLabel" name="label_2">
     <property name="text">
      <string>密码:</string>
     </property>
    </widget>
    <widget class="QLabel" name="label_3">
     <property name="text">
      <string>测试IP:</string>
     </property>
    </widget>
    <widget class="QLabel" name="label_4">
     <property name="text">
      <string>订阅:</string>
     </property>
    </widget>
   </widget>
   <widget class="QSplitter" name="splitter_6">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>250</y>
      <width>351</width>
      <height>204</height>
     </rect>
    </property>
    <property name="orientation">
     <enum>Qt::Vertical</enum>
    </property>
    <widget class="QLabel" name="label_5">
     <property name="text">
      <string>信息</string>
     </property>
    </widget>
    <widget class="QTextBrowser" name="textBrowser_msg"/>
   </widget>
   <widget class="QSplitter" name="splitter_7">
    <property name="geometry">
     <rect>
      <x>200</x>
      <y>20</y>
      <width>161</width>
      <height>121</height>
     </rect>
    </property>
    <property name="maximumSize">
     <size>
      <width>271</width>
      <height>16777215</height>
     </size>
    </property>
    <property name="orientation">
     <enum>Qt::Vertical</enum>
    </property>
    <widget class="QSplitter" name="splitter_5">
     <property name="maximumSize">
      <size>
       <width>271</width>
       <height>16777215</height>
      </size>
     </property>
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <widget class="QSplitter" name="splitter_4">
      <property name="maximumSize">
       <size>
        <width>271</width>
        <height>16777215</height>
       </size>
      </property>
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <widget class="QPushButton" name="pushButton_conn">
       <property name="maximumSize">
        <size>
         <width>271</width>
         <height>16777215</height>
        </size>
       </property>
       <property name="text">
        <string>连接</string>
       </property>
      </widget>
      <widget class="QPushButton" name="pushButton_disconn">
       <property name="maximumSize">
        <size>
         <width>271</width>
         <height>16777215</height>
        </size>
       </property>
       <property name="text">
        <string>断开</string>
       </property>
      </widget>
     </widget>
     <widget class="QSplitter" name="splitter">
      <property name="maximumSize">
       <size>
        <width>271</width>
        <height>16777215</height>
       </size>
      </property>
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
      <widget class="QLabel" name="label_6">
       <property name="maximumSize">
        <size>
         <width>150</width>
         <height>16777215</height>
        </size>
       </property>
       <property name="text">
        <string>端口:</string>
       </property>
      </widget>
      <widget class="QSpinBox" name="spinBox">
       <property name="minimumSize">
        <size>
         <width>35</width>
         <height>20</height>
        </size>
       </property>
       <property name="maximumSize">
        <size>
         <width>116</width>
         <height>16777215</height>
        </size>
       </property>
      </widget>
     </widget>
    </widget>
    <widget class="QPushButton" name="pushButton_dy">
     <property name="maximumSize">
      <size>
       <width>271</width>
       <height>16777215</height>
      </size>
     </property>
     <property name="text">
      <string>订阅</string>
     </property>
    </widget>
   </widget>
   <widget class="QWidget" name="layoutWidget">
    <property name="geometry">
     <rect>
      <x>200</x>
      <y>150</y>
      <width>161</width>
      <height>31</height>
     </rect>
    </property>
    <layout class="QHBoxLayout" name="horizontalLayout">
     <item>
      <widget class="QPushButton" name="pushButton_clientId">
       <property name="maximumSize">
        <size>
         <width>271</width>
         <height>16777215</height>
        </size>
       </property>
       <property name="text">
        <string>生成CID</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QLabel" name="label_8">
       <property name="maximumSize">
        <size>
         <width>150</width>
         <height>16777215</height>
        </size>
       </property>
       <property name="text">
        <string>QoS:</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QSpinBox" name="spinBox_QoS">
       <property name="minimumSize">
        <size>
         <width>35</width>
         <height>20</height>
        </size>
       </property>
       <property name="maximumSize">
        <size>
         <width>116</width>
         <height>16777215</height>
        </size>
       </property>
      </widget>
     </item>
    </layout>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>380</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <qmqtt_client.h>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();


private slots:
    void onMQTT_Received(const QMQTT::Message &message);
    void onMQTT_subscribed(const QString& topic);

    void on_pushButton_conn_clicked();

    void on_pushButton_disconn_clicked();

    void on_pushButton_dy_clicked();

    void on_pushButton_clientId_clicked();

    void on_pushButton_send_clicked();

private:
    Ui::MainWindow *ui;
    QMQTT::Client * client;

};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qmqtt_client.h>
#include <qmqtt_message.h>
#include <qdatetime.h>
#include <QMessageBox>
#include <QDateTime>
using namespace QMQTT;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{

    ui->setupUi(this);
    ui->spinBox->setMaximum(99999);
    ui->spinBox->setValue(1883);
    ui->spinBox_QoS->setMaximum(2);
    ui->spinBox_QoS->setMinimum(0);

    client = new Client();

    connect(client,SIGNAL(received(const QMQTT::Message&)),this,SLOT(onMQTT_Received(const QMQTT::Message&)));
    connect(client,SIGNAL(subscribed(const QString&)),this,SLOT(onMQTT_subscribed(const QString&)));

}

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


void MainWindow::onMQTT_Received(const QMQTT::Message &message)
{
    QString strPaylaod = message.payload();
    //QMessageBox::warning(this,"payload",strPaylaod,QMessageBox::Yes,QMessageBox::No);
    QString strLine = ui->textBrowser_msg->toPlainText();

    QDateTime dt = QDateTime::currentDateTime();
    QString strDate = dt.toString(Qt::SystemLocaleLongDate);//日期格式自定义
    strLine += "\n";
    strLine += strDate;
    strLine += "\n";
    strLine += strPaylaod;

    ui->textBrowser_msg->setText(strLine);

}
void MainWindow::onMQTT_subscribed(const QString &topic)
{

    qDebug() << topic;
     QMessageBox::warning(this,"订阅成功",topic,QMessageBox::Yes);

}

void MainWindow::on_pushButton_conn_clicked()
{
    // 取出ip,端口
    QHostAddress host(QString(ui->lineEdit_ip->text()));
    quint16 port = ui->spinBox->value();
    quint16 QosNum = ui->spinBox_QoS->value();
    QString cId = ui->lineEdit_clientId->text();
    QString username = ui->lineEdit_username->text();
    QString psword = ui->lineEdit_psword->text();
    QString ip = ui->lineEdit_ip->text();

    if(cId == "" || username == "" || psword == "" || ip == "")
    {
        QMessageBox::warning(this,"提示","请将信息输入完整",QMessageBox::Yes);
        return;
    }

    client->setHost(host);
    client->setPort(port);
    client->setWillQos(QosNum);
    client->setClientId(cId);
    client->connectToHost();


}

void MainWindow::on_pushButton_disconn_clicked()
{
    client->disconnectFromHost();
}

void MainWindow::on_pushButton_dy_clicked()
{
    client->setWillTopic(ui->lineEdit_dy->text());
    client->subscribe(ui->lineEdit_dy->text(), 0);
}

void MainWindow::on_pushButton_clientId_clicked()
{
    qsrand(QDateTime::currentMSecsSinceEpoch());//为随机值设定一个seed

    const char chrs[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    int chrs_size = sizeof(chrs);

    char* ch = new char[chrs_size + 1];
    memset(ch, 0, chrs_size + 1);
    int randomx = 0;
    for (int i = 0; i < 20; ++i)
    {
        randomx= rand() % (chrs_size - 1);
        ch[i] = chrs[randomx];
    }

    QString ret(ch);
    delete[] ch;
    ui->lineEdit_clientId->setText(ret);

}

void MainWindow::on_pushButton_send_clicked()
{
    // 发送消息
   /* client->setWillMessage("111111");
    client->disconnectFromHost();
    client->connectToHost();*/


    // 测试代码
    client->disconnectFromHost();
    QHostAddress host(QString(ui->lineEdit_ip->text()));
    quint16 port = ui->spinBox->value();
    quint16 QosNum = ui->spinBox_QoS->value();
    QString cId = ui->lineEdit_clientId->text();
    QString username = ui->lineEdit_username->text();
    QString psword = ui->lineEdit_psword->text();
    QString ip = ui->lineEdit_ip->text();

    if(cId == "" || username == "" || psword == "" || ip == "")
    {
        QMessageBox::warning(this,"提示","请将信息输入完整",QMessageBox::Yes);
        return;
    }

    client->setHost(host);
    client->setPort(port);
    client->setWillQos(QosNum);
    client->setClientId(cId);
    client->connectToHost();
    QByteArray qbyte = ui->lineEdit_sendMsg->text().toUtf8();
    client->setWillMessage(qbyte);
    client->disconnectFromHost();

    // 恢复连接
    client->connectToHost();

}

原文连接:https://blog.csdn.net/qq_40535097/article/details/106457153


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞1
打赏
分享
最新回复 (4)
雪    币: 9614
活跃值: (1826)
能力值: ( LV5,RANK:73 )
在线值:
发帖
回帖
粉丝
Sprite雪碧 1 2020-6-1 06:15
2
1
.a 文件是 linux 下的库文件,windows 下就是 .lib
雪    币: 19586
活跃值: (60108)
能力值: (RANK:125 )
在线值:
发帖
回帖
粉丝
Editor 2020-6-1 14:42
3
0
CSDN博主秃头的JJ,是你本人吗?
雪    币: 1928
活跃值: (5894)
能力值: ( LV7,RANK:118 )
在线值:
发帖
回帖
粉丝
tutuj 2020-6-1 23:08
4
0
是的
雪    币: 1928
活跃值: (5894)
能力值: ( LV7,RANK:118 )
在线值:
发帖
回帖
粉丝
tutuj 2020-6-1 23:09
5
0
谢谢2楼大佬,学到了
游客
登录 | 注册 方可回帖
返回