笔记

  在QT的学习中,经常会遇到上位机采集相关数据,然后提交至后端服务器的情况,提交方式有GETPOST 。本篇文章主要记录 QT udp POST 提交数据至服务器,并接收服务器返回的JSON状态码.

在QT5中,pro文件要包含QT += network

/*
*引入 QNetworkRequest、QNetworkReply、QNetworkAccessManager 类;
*一般这三个类是一起使用的,用于应用程序发送和响应网络请求;
*
*引入QJsonDocument、QJsonArray、QJsonObject类
*用于解析服务器返回的JSON数据;
*/
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>

#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>

//声明一个QNetworkAccessManager类
QNetworkAccessManager *m_accessManager;
//新建一个QNetworkAccessManager 对象;
m_accessManager = new QNetworkAccessManager(this);
//绑定信号槽;
QObject::connect(m_accessManager, SIGNAL(finished(QNetworkReply*)), this,SLOT(finishedSlot(QNetworkReply*)));

这里先声明了一个QNetworkAccessManager类,然后新建一个m_accessManager 对象,再对这个对象绑定了槽函数,槽函数是:finishedSlot(QNetworkReply*),触发信号是:finishedSlot(QNetworkReply *reply)

客户端发送数据
发送网络请求是QNetworkReply* reply = m_accessManager->post(request,postData),它将组装好的数据以链接形式POST 到服务器,然后监听服务器返回的状态;

QNetworkRequest request;      //声明一个网络请求对象 request ; 

//这里是向 http://127.0.0.1:8080/abc/def? post 数据;
request.setUrl(QUrl("http://127.0.0.1:8080/abc/def?"));  

QByteArray postData;    //新建一个数组;

//数据提交的格式为:http://127.0.0.1:8080/abc/def?id=123456&key=abc123
//组装数据;
postData.append("id="); 
postData.append(serial_num);
postData.append("&");
postData.append("key=");
postData.append(key_num);

//发起网络请求
QNetworkReply* reply = m_accessManager->post(request,postData);

接收服务器数据,槽函数:
接收网络数据是由finishedSlot槽函数完成,若上一步POST成功,则会收到服务器返回的状态码+JSON数据,若POST失败,则会返回对应的错误码。

void Widget::finishedSlot(QNetworkReply *reply)
{
    if (reply->error() == QNetworkReply::NoError)
     {
        QByteArray bytes = reply->readAll();  //读取所有接收字节;
        
        //声明一个QJsonObject 对象 json_object_reg,用于接收读取到的数据
        QJsonObject json_object_reg = QJsonDocument::fromJson(bytes).object();
        
        //提取"msg"字段的数据
        msg_reg = json_object_reg.value("msg").toString();
        qDebug() << msg_reg;    //打印
        
        //提取"code"字段的数据
        int code_reg = json_object_reg.value("code").toInt();
        qDebug() << code_reg;    //打印
        
    }
    else  //提交异常,返回错误码;
     {
         QMessageBox::information(this, "警告","数据提交失败!");

         qDebug()<<"handle errors here";
         QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
         //statusCodeV是HTTP服务器的相应码,reply->error()是Qt定义的错误码,可以参考QT的文档

         ui->textBrowser->appendPlainText("\n found error ....code:" + statusCodeV.toInt());
         //ui->textBrowser->appendPlainText(statusCodeV.toInt());

         qDebug( "found error ....code: %d %d\n", statusCodeV.toInt(), (int)reply->error());

         qDebug(qPrintable(reply->errorString()));
     }

     reply->deleteLater();
}

其中QJsonObject json_object_reg = QJsonDocument::fromJson(bytes).object(),是将读取数据序列转为JSON格式数据,并方便后面解析操作;




总结:本篇文章实现了一个简单的udp post 范例,通过给定的URL 提交采集到的数据,并接收、解析服务器返回的JSON数据,虽然简单,但很实用、容易理解;

PS:与UDP socket 编程不同的是,此方法在接收消息时不需要绑定端口号,发送消息则需要指定端口号。下一篇文章记录UDP socket 编程

最后修改:2019 年 09 月 20 日
您的支持就是我持续更新的动力!