HTTP協議學習
協議的相關學習可以參考這篇 csdn學習連接
總體流程如下
HTTP服務器
監聽ip和端口,有連接時接收請求,發送回復
server.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_httpServer.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <QtNetwork>
#include <QNetworkAccessManager>
#include <QDebug>
#include <QJsonObject>
#include <QJsonDocument>
#include <QDateTime>class httpServer : public QMainWindow
{Q_OBJECTpublic:httpServer(QWidget *parent = nullptr);~httpServer();// 啟動 HTTP 服務器,默認監聽 8080 端口void start(quint16 port = 8080);public slots:// 當有新的 TCP 連接到來時,處理連接的槽函數void onNewConnection();private:Ui::httpServerClass ui;
};
回應使用json構建,我這邊是添加了url的判斷,需要在url里有/getData
我才會回復對應的數據
server.cpp
#include "httpServer.h"httpServer::httpServer(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);}httpServer::~httpServer()
{}void httpServer::start(quint16 port)
{//創建TCP服務器實例監聽QTcpServer* server = new QTcpServer(this);//有新鏈接時connect(server, &QTcpServer::newConnection, this, &httpServer::onNewConnection);//啟動監聽if (!server->listen(QHostAddress::Any, port)) {qDebug() << "Server failed to start:" << server->errorString();}else {qDebug() << "Server started at port" << port;}
}void httpServer::onNewConnection()
{//獲取當前觸發的server對象QTcpServer* server = qobject_cast<QTcpServer*>(sender());//獲取客戶端的socket連接QTcpSocket *clientSocket = server->nextPendingConnection();connect(clientSocket, &QTcpSocket::readyRead, [clientSocket](){//讀取客戶端發來的請求(完整的http請求)QByteArray request = clientSocket->readAll();qDebug() << "Request received:\n" << request;//構建Json對象QJsonObject json;json["time"] = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");json["ocrCode"] = "ABC123456";json["rollCode"] = "ROLL7890";QJsonDocument doc(json);QByteArray body = doc.toJson(QJsonDocument::Compact);//壓縮格式(無縮進)//構建http響應頭// 構造 HTTP 響應頭QByteArray response;response.append("HTTP/1.1 200 OK\r\n");response.append("Content-Type: application/json; charset=utf-8\r\n");response.append("Content-Length: " + QByteArray::number(body.size()) + "\r\n");response.append("Connection: close\r\n");response.append("\r\n");response.append(body); // 加上 JSON 內容//發送HTTP響應clientSocket->write(response);//斷開連接clientSocket->disconnectFromHost();});
}
最后在main.cpp
里調用m_pServer.start(8080);
啟動監聽端口
在HTTP頭上添加上
response.append("Access-Control-Allow-Origin: *\r\n"); // 如果前端跨域請求,添加上這個網頁訪問也能看到
可以直接用瀏覽器去訪問查看結果
客戶端
發送http請求,對服務器的回應做出json解析
client.h#pragma once#include <QtWidgets/QMainWindow>
#include "ui_httpclient.h"
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTimer>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonParseError>class httpclient : public QMainWindow
{Q_OBJECTpublic:httpclient(QWidget *parent = nullptr);~httpclient();// 發起 GET 請求void get(const QUrl &url);private slots:// 網絡請求完成后的處理槽函數void onFinished(QNetworkReply *reply);private:Ui::httpclientClass ui;// Qt 的網絡訪問管理器,支持異步 HTTP 請求QNetworkAccessManager m_manager;QTimer* m_pTimer;
};
客戶端實例通過get()
函數發起請求
client.cpp#include "httpclient.h"httpclient::httpclient(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);// 請求完成后觸發 onFinished()connect(&m_manager, &QNetworkAccessManager::finished, this, &httpclient::onFinished);m_pTimer = new QTimer(this);m_pTimer->setInterval(10000);m_pTimer->start();connect(m_pTimer, &QTimer::timeout, [=]() {this->get(QUrl("http://192.168.1.168:8080/getData")); });
}httpclient::~httpclient()
{}//發起get請求
void httpclient::get(const QUrl & url)
{QNetworkRequest request(url); //構造請求m_manager.get(request); //異步發送get請求
}//收到服務器響應后調用
void httpclient::onFinished(QNetworkReply *reply)
{if (reply->error() == QNetworkReply::NoError){//讀取服務器返回的內容QByteArray data = reply->readAll();qDebug() << "Response:" << data; QJsonParseError err;QJsonDocument doc = QJsonDocument::fromJson(data, &err);if (err.error == QJsonParseError::NoError && doc.isObject()){QJsonObject obj = doc.object();QString time = obj["time"].toString();QString ocrCode = obj["ocrCode"].toString();QString rollCode = obj["rollCode"].toString();qDebug() << "Parsed JSON:";qDebug() << " Time:" << time;qDebug() << " OCR Code:" << ocrCode;qDebug() << " Roll Code:" << rollCode;ui.textEdit->append(time);ui.textEdit->append(ocrCode);ui.textEdit->append(rollCode);}else {qDebug() << "Invalid JSON:" << err.errorString();ui.textEdit->append("Invalid JSON:");}}else {qDebug() << "Error:" << reply->errorString(); // 網絡錯誤ui.textEdit->append("Error:"+reply->errorString());}reply->deleteLater(); //釋放資源
}