Qt利用UDP通信来传输JSON数据以及接收并解析JSON数据
Qt利用UDP通信来传输JSON数据以及接收并解析JSON数据
·
JSON常来做数据传输的格式,本文采用UDP通信来传递JSON格式的数据
- UDP Server端采用Qt Widgets技术
- UDP Client端采用Qt Quick技术
效果如图所示: |
- Server端代码
- mainwidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
#include "udpsendunit.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWidget; }
QT_END_NAMESPACE
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget(QWidget *parent = nullptr);
~MainWidget();
static void appendLogToEdit(QtMsgType type, const QMessageLogContext &context, const QString &msg);
private slots:
void on_sendBtn_clicked();
signals:
private:
void initUI();
void initConnect();
private:
UdpSendUnit* m_udpSend;
private:
Ui::MainWidget *ui;
static MainWidget *mainWidget;
};
#endif // MAINWIDGET_H
- mainwidget.cpp
#include "mainwidget.h"
#include "ui_mainwidget.h"
#include <QDebug>
#include <QDateTime>
#include <QMutex>
#include <QFile>
MainWidget *MainWidget::mainWidget = nullptr;
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MainWidget)
{
ui->setupUi(this);
MainWidget::mainWidget = this;
qInstallMessageHandler(appendLogToEdit);
this->setWindowTitle("XX数据采集中心");
this->setFixedSize(500, 400);
initUI();
m_udpSend = new UdpSendUnit(ui->IP_Liedt->text(), ui->Port_Liedt->text().toInt(), this);
initConnect();
}
MainWidget::~MainWidget()
{
delete ui;
}
void MainWidget::appendLogToEdit(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
Q_UNUSED(context);
static QMutex mutex;
mutex.lock();
QString fileName = QDateTime::currentDateTime().toString("yyyyMMdd-hh") + ".log";
QString time;
time.append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") + " ");
if(MainWidget::mainWidget != nullptr)
{
MainWidget::mainWidget->ui->textBrowser->append(time + msg);
}
mutex.unlock();
}
void MainWidget::on_sendBtn_clicked()
{
m_udpSend->start();
}
void MainWidget::initUI()
{
ui->IP_Lbl->setText("RemoteHost:");
ui->Port_Lbl->setText("Port:");
ui->name_Lbl->setText("Name:");
ui->beepValue_Lbl->setText("BeepValue:");
ui->sendBtn->setText("发送");
ui->IP_Liedt->setText("127.0.0.1");
ui->Port_Liedt->setText("18000");
ui->name_Liedt->setText("high");
ui->beepValue_Liedt->setText("1");
ui->textBrowser->setStyleSheet("QTextBrowser{ color: \"red\"; font: bold 16px \"微软雅黑\" }");
ui->textBrowser->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
ui->textBrowser->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}
void MainWidget::initConnect()
{
connect(ui->name_Liedt, &QLineEdit::textChanged, m_udpSend, &UdpSendUnit::nameValue_slot);
connect(ui->beepValue_Liedt, &QLineEdit::textChanged, m_udpSend, &UdpSendUnit::beepValue_slot);
}
- udpsendunit.h
#ifndef UDPSENDUNIT_H
#define UDPSENDUNIT_H
#include <QObject>
#include <QThread>
#include <QUdpSocket>
#include <QJsonObject>
#include <QJsonDocument>
class UdpSendUnit : public QThread
{
Q_OBJECT
public:
explicit UdpSendUnit(QString ip, int port, QObject *parent = nullptr);
protected:
void run() override;
signals:
public slots:
void nameValue_slot(QString nameStr);
void beepValue_slot(QString beepStr);
private:
QUdpSocket* m_socket;
QJsonObject m_json;
QString m_ip;
int m_port;
QString m_name;
int m_beep;
bool m_flag;
};
#endif // UDPSENDUNIT_H
- udpsendunit.cpp
#include "udpsendunit.h"
#include <QDebug>
#include <QTextCursor>
UdpSendUnit::UdpSendUnit(QString ip, int port, QObject *parent) : QThread(parent)
{
m_ip = ip;
m_port = port;
m_flag = false;
m_socket = new QUdpSocket(this);
m_socket->bind(QHostAddress::AnyIPv4, 9988);
m_name = "H";
m_beep = 1;
}
void UdpSendUnit::run()
{
long long flag = 0;
while(true){
flag++;
m_json.insert("name", m_name);
if(m_flag)
{
m_json.insert("beep", m_beep);
m_flag = false;
flag = m_beep;
}
else{
m_json.insert("beep", flag);
}
QJsonDocument _jsonDoc(m_json);
QByteArray _byteArray = _jsonDoc.toJson(QJsonDocument::Indented);
//QString strTmp = QString(_jsonDoc.toJson(QJsonDocument::Indented));
QString strTmp = QString(_jsonDoc.toJson(QJsonDocument::Compact));
qDebug() << strTmp;
m_socket->writeDatagram(_byteArray, QHostAddress(m_ip), m_port);
QThread::sleep(1);
}
}
void UdpSendUnit::nameValue_slot(QString nameStr)
{
m_name = nameStr;
}
void UdpSendUnit::beepValue_slot(QString beepStr)
{
m_beep = beepStr.toInt();
m_flag = true;
m_json.insert("beep", m_beep);
}
- main.cpp
#include "mainwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWidget w;
w.show();
return a.exec();
}
- Client端代码
- udprecvunit.h
#ifndef UDPRECVUNIT_H
#define UDPRECVUNIT_H
#include <QObject>
#include <QThread>
#include <QUdpSocket>
class UdpRecvUnit : public QThread
{
Q_OBJECT
public:
explicit UdpRecvUnit(QObject *parent = nullptr);
Q_PROPERTY(QString nameStr READ getAlias WRITE setAlias NOTIFY aliasChanged)
Q_PROPERTY(int beepInt READ getBeep WRITE setBeep NOTIFY beepChanged)
Q_PROPERTY(QString jsonValue READ getJsonValue WRITE setJsonValue NOTIFY jsonValueChanged)
QString getAlias() const;
int getBeep() const;
QString getJsonValue() const;
public slots:
void setAlias(QString nameStr);
void setBeep(int beepInt);
void setJsonValue(QString jsonValue);
protected:
void run() override;
private:
void analyseData(QByteArray data);
signals:
void aliasChanged(QString nameStr);
void beepChanged(int beepInt);
void jsonValueChanged(QString jsonValue);
private:
QUdpSocket* m_socket;
QString m_nameStr;
int m_beepInt;
QString m_jsonValue;
};
#endif // UDPRECVUNIT_H
- udprecvunit.cpp
#include "udprecvunit.h"
#include <QJsonObject>
#include <QJsonDocument>
#include <QDebug>
UdpRecvUnit::UdpRecvUnit(QObject *parent) : QThread(parent)
{
m_socket = new QUdpSocket(this);
m_socket->bind(QHostAddress::AnyIPv4, 18000);
m_nameStr = "Test";
m_beepInt = 1;
}
void UdpRecvUnit::run()
{
while(true){
if(m_socket->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(m_socket->pendingDatagramSize());
m_socket->readDatagram(datagram.data(), datagram.size());
analyseData(datagram);
}
QThread::msleep(1500);
}
}
void UdpRecvUnit::analyseData(QByteArray data)
{
QJsonParseError jsonError;
QJsonDocument parseDoc = QJsonDocument::fromJson(data, &jsonError);
if(jsonError.error == QJsonParseError::NoError)
{
if(parseDoc.isObject()){
QJsonObject obj = parseDoc.object();
//qDebug() << obj.value("name").toString();
//qDebug() << obj.value("beep").toInt();
m_nameStr = obj.value("name").toString();
m_beepInt = obj.value("beep").toInt();
m_jsonValue = QString(parseDoc.toJson(QJsonDocument::Indented));
}
}
}
QString UdpRecvUnit::getAlias() const
{
return m_nameStr;
}
int UdpRecvUnit::getBeep() const
{
return m_beepInt;
}
void UdpRecvUnit::setAlias(QString nameStr)
{
if (m_nameStr == nameStr)
return;
m_nameStr = nameStr;
emit aliasChanged(m_nameStr);
}
void UdpRecvUnit::setBeep(int beepInt)
{
if (m_beepInt == beepInt)
return;
m_beepInt = beepInt;
emit beepChanged(m_beepInt);
}
QString UdpRecvUnit::getJsonValue() const
{
return m_jsonValue;
}
void UdpRecvUnit::setJsonValue(QString jsonValue)
{
if (m_jsonValue == jsonValue)
return;
m_jsonValue = jsonValue;
emit jsonValueChanged(m_jsonValue);
}
- main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "udprecvunit.h"
#include "uidata.h"
#include <QtQml>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
UdpRecvUnit* m_udpRecv = new UdpRecvUnit();
m_udpRecv->start();
UIData* m_uiData = new UIData();
engine.rootContext()->setContextProperty("UIData", m_uiData);
engine.rootContext()->setContextProperty("UDPRecv", m_udpRecv);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
- uidata.h
#ifndef UIDATA_H
#define UIDATA_H
#include <QObject>
class UIData : public QObject
{
Q_OBJECT
public:
explicit UIData(QObject *parent = nullptr);
Q_PROPERTY(QString nameStr READ getAlias WRITE setAlias NOTIFY aliasChanged)
Q_PROPERTY(int beepInt READ getBeep WRITE setBeep NOTIFY beepChanged)
QString getAlias() const;
int getBeep() const;
public slots:
void setAlias(QString nameStr);
void setBeep(int beepInt);
signals:
void aliasChanged(QString nameStr);
void beepChanged(int beepInt);
private:
QString m_nameStr;
int m_beepInt;
};
#endif // UIDATA_H
- uidata.h
#include "uidata.h"
UIData::UIData(QObject *parent) : QObject(parent)
{
}
QString UIData::getAlias() const
{
return m_nameStr;
}
int UIData::getBeep() const
{
return m_beepInt;
}
void UIData::setAlias(QString nameStr)
{
if (m_nameStr == nameStr)
return;
m_nameStr = nameStr;
emit aliasChanged(m_nameStr);
}
void UIData::setBeep(int beepInt)
{
if (m_beepInt == beepInt)
return;
m_beepInt = beepInt;
emit beepChanged(m_beepInt);
}
- main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls 1.4 as Controls14
import QtQuick.Dialogs 1.2
import Qt.labs.calendar 1.0
import QtQuick.Layouts 1.12
Window {
id: root;
visible: true
width: 640
height: 480
title: qsTr("XX监视系统")
property alias dlgContent : textContainer.text
property alias jsonContent : txtContent.text
ColumnLayout{
id: clmnLy;
anchors.fill: parent;
spacing: 20;
RowLayout{
//anchors.top: parent.top;
Layout.fillWidth: true;
Layout.maximumWidth: 80;
spacing: 20;
TextEdit {
id: txt;
//x: (parent.width - txt.width) / 2;
//y: (parent.height - txt.height) / 2;
//anchors.left: btn.right;
//y: 20;
width: 240;
text: "highlander";
font.family: "Helvetica";
font.pointSize: 18;
color: "blue";
focus: true;
}
Button{
id: btn;
//x: (parent.width - btn.width) / 2;
//y: 20;
text: qsTr("弹窗");
onClicked: {
console.log("MessageBox Test");
modelessDlg.open();
}
}
}
Rectangle{
height: 2;
color: "yellow";
width: root.width;
}
Rectangle{
id: rec;
width: root.width;
height: root.height;
Layout.fillWidth: true;
/*
TextEdit{
id: txtContent;
anchors.fill: parent;
font.pointSize: 20;
wrapMode: TextEdit.Wrap;
readOnly: true;
MouseArea {
anchors.fill: parent;
drag.target: txtContent;
drag.axis: Drag.YAxis;
drag.minimumY: -(parent.height-480);
drag.maximumY: 0
}
}
*/
ScrollView{
anchors.fill: parent;
TextArea{
id: txtContent;
// anchors.fill: parent;
font.pointSize: 18;
wrapMode: TextEdit.Wrap;
readOnly: true;
color: "green";
}
}
}
}
Dialog{
id: modelessDlg;
visible: false;
modality: "NonModal";
standardButtons: Dialog.Ok;
title: "报警";
Text {
id: textContainer
anchors.fill: parent
horizontalAlignment: Qt.AlignLeft
verticalAlignment: Qt.AlignTop
color: "red";
font.pointSize: 18;
}
onAccepted: {
console.log("OK clicked.");
UDPRecv.beepInt = UDPRecv.beepInt + 1;
}
onRejected: {
UDPRecv.beepInt = 200;
}
// 自定义内容
//contentItem: Rectangle{
// color: "red";
// implicitWidth: 300;
// implicitHeight: 200;
// Text {
// anchors.centerIn: parent;
// text: qsTr("text");
// }
//}
/*
添加日历控件
Controls14.Calendar {
id: calendar
onDoubleClicked: dateDialog.click(StandardButton.Save)
}
*/
}
//定时器
Timer {
interval: 1000;
running: true;
repeat: true
onTriggered: {
txt.text = UDPRecv.nameStr;
if(UDPRecv.beepInt % 5 == 0)
{
//modelessDlg.open();
modelessDlg.visible = true;
console.log("报警提示显示");
}
else if(UDPRecv.beepInt % 9 == 0)
{
//modelessDlg.close();
modelessDlg.visible = false;
console.log("报警提示隐藏");
}
dlgContent = UDPRecv.beepInt;
//console.log(UDPRecv.beepInt);
jsonContent += UDPRecv.jsonValue;
}
}
}
- 工程文件添加配置
QT += network
DESTDIR = bin
CONFIG -= debug_and_release
MOC_DIR = tmp/moc
RCC_DIR = tmp/rcc
UI_DIR = tmp/ui
OBJECTS_DIR = tmp/obj

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)