国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【QT HTTP】使用QtNetwork模塊制作基于HTTP請求的C/S架構(gòu)

這篇具有很好參考價值的文章主要介紹了【QT HTTP】使用QtNetwork模塊制作基于HTTP請求的C/S架構(gòu)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

qtcpsocket自己構(gòu)造http格式,QT,C++,qt,http,c語言,C++

  • ???♂? 作者:海碼007
  • ?? 專欄:C++專欄
  • ?? 標題:【QT HTTP】使用QtNetwork模塊制作基于HTTP請求的C/S架構(gòu)
  • ?? 寄語:書到用時方恨少,事非經(jīng)過不知難。
  • ?? 最后:文章作者技術(shù)和水平有限,如果文中出現(xiàn)錯誤,希望大家能指正!

0 引言

  • 最近項目涉及到網(wǎng)絡(luò)HTTP相關(guān)內(nèi)容,需要處理客戶端發(fā)送的POST、GET等請求。所以本文使用QT的QtNetwork模塊來實現(xiàn)一個簡單的發(fā)送POST、GET請求的客戶端,然后響應(yīng)POST、GET請求的服務(wù)器。
  • 本文涉及到一些HTTP的基本知識,可以參考博主之前的文章:計算機網(wǎng)絡(luò)HTTP協(xié)議

HTTP(Hypertext Transfer Protocol)是一種應(yīng)用層協(xié)議,它是建立在傳輸控制協(xié)議(TCP)之上的。在使用HTTP進行客戶端和服務(wù)器之間的通信時,實際上是通過TCP協(xié)議來傳輸HTTP消息。

TCP是一種面向連接的協(xié)議,它提供了可靠的、按順序傳送的字節(jié)流,確保數(shù)據(jù)的完整性和可靠性。HTTP利用TCP的這些特性來確保請求和響應(yīng)的可靠傳輸。

HTTP消息包括請求報文和響應(yīng)報文。請求報文由客戶端發(fā)送給服務(wù)器,而響應(yīng)報文由服務(wù)器發(fā)送給客戶端。這些報文包含了與所請求的資源或所提供的信息相關(guān)的頭部(headers)和實體體(entity body)。

總體而言,HTTP建立在TCP協(xié)議的基礎(chǔ)之上,它定義了一種規(guī)范,用于客戶端和服務(wù)器之間的通信,而TCP則提供了底層的可靠數(shù)據(jù)傳輸機制。

1 HTTP基本知識

1.1 請求類型

HTTP(Hypertext Transfer Protocol)協(xié)議 定義了多種請求方法,也稱為HTTP請求類型或HTTP動詞。這些請求方法表示客戶端希望對特定資源執(zhí)行的操作。以下是常見的HTTP請求類型、其功能和應(yīng)用場景:

  1. GET:

    • 功能: 用于從服務(wù)器獲取指定資源的信息。請求的參數(shù)通常附在URL后面,通過查詢字符串傳遞。
    • 應(yīng)用場景: 用于查看網(wǎng)頁、下載文件、獲取數(shù)據(jù)等。是冪等的,不應(yīng)該對服務(wù)器產(chǎn)生影響。(我們輸入一個網(wǎng)址,其實就是從服務(wù)器獲得一個HTML文件,然后瀏覽器內(nèi)核再根據(jù)其將內(nèi)容繪制出來)
  2. POST:

    • 功能: 用于向服務(wù)器提交數(shù)據(jù),通常用于表單提交。請求的參數(shù)通常包含在請求體中。
    • 應(yīng)用場景: 用于創(chuàng)建新資源、提交表單數(shù)據(jù)、上傳文件等??赡軐Ψ?wù)器產(chǎn)生影響。不是冪等的,多次相同的POST請求可能產(chǎn)生不同的結(jié)果。
  3. PUT:

    • 功能: 用于向服務(wù)器上傳新資源,或者更新已存在的資源。請求的參數(shù)通常包含在請求體中。
    • 應(yīng)用場景: 用于創(chuàng)建或更新資源。是冪等的,多次相同的PUT請求應(yīng)該產(chǎn)生相同的結(jié)果。
  4. DELETE:

    • 功能: 用于請求服務(wù)器刪除指定的資源
    • 應(yīng)用場景: 用于刪除指定資源。是冪等的,多次相同的DELETE請求應(yīng)該產(chǎn)生相同的結(jié)果。
  5. PATCH:

    • 功能: 用于對資源進行部分更新。請求的參數(shù)通常包含在請求體中,表示對資源的局部修改。
    • 應(yīng)用場景: 用于對資源進行局部更新,而不是替換整個資源。
  6. HEAD:

    • 功能: 類似于GET請求,但服務(wù)器只返回響應(yīng)頭,不返回實體主體。常用于檢查資源的元信息,如是否存在、是否已經(jīng)修改等。
    • 應(yīng)用場景: 用于獲取資源的頭部信息,而不需要獲取整個資源的內(nèi)容。
  7. OPTIONS:

    • 功能: 用于獲取目標資源支持的通信選項??蛻舳丝梢酝ㄟ^這個方法了解服務(wù)器支持的方法。
    • 應(yīng)用場景: 用于確定服務(wù)器支持的方法,以及支持的頭信息等。
  8. TRACE:

    • 功能: 用于在目標服務(wù)器上執(zhí)行一個消息環(huán)回測試,客戶端發(fā)送的請求會在最終的服務(wù)器上返回,用于診斷和調(diào)試。
    • 應(yīng)用場景: 主要用于網(wǎng)絡(luò)診斷,通常不會在實際應(yīng)用中直接使用。

選擇適當(dāng)?shù)腍TTP請求類型取決于具體的操作和業(yè)務(wù)需求。每種請求類型都有其獨特的功能和應(yīng)用場景,使其適用于不同的情境。

1.2 HTTP請求報文格式

HTTP請求報文是客戶端發(fā)送給服務(wù)器的文本信息,包含請求的各種參數(shù)和頭信息。它的基本格式如下:

<Method> <Request-URI> <HTTP-Version>
<Headers>

<Optional Request Body>

其中,各部分的含義如下:

  • <Method>:HTTP請求方法,例如GET、POST、PUT等。
  • <Request-URI>:請求的資源標識符,通常是一個URL。
  • <HTTP-Version>:使用的HTTP協(xié)議版本,例如HTTP/1.1。
  • <Headers>:包含多行的頭部信息,每行都包含一個頭字段和對應(yīng)的值。
  • <Optional Request Body>:可選的請求體,用于包含請求時需要發(fā)送的數(shù)據(jù),例如POST請求中的表單數(shù)據(jù)。

以下是一個具體的例子:

GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
Upgrade-Insecure-Requests: 1

在這個例子中:

  • 請求方法是GET。
  • 請求的資源標識符是/index.html。
  • 使用的HTTP協(xié)議版本是HTTP/1.1。
  • 請求頭部包含了Host、User-AgentAccept等字段,每個字段都以<header-name>: <header-value>的形式呈現(xiàn)。
  • 由于GET請求通常不包含請求體,因此沒有<Optional Request Body>部分。

對于包含請求體的請求,例如POST請求,請求體會緊隨請求頭部,并用一個空行分隔。例如:

POST /submit-form HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 23

username=johndoe&password=123

在這個例子中,請求體包含了表單數(shù)據(jù)username=johndoe&password=123,并通過Content-Type頭字段指定了數(shù)據(jù)的格式。

1.3 HTTP響應(yīng)報文格式

HTTP響應(yīng)報文是服務(wù)器返回給客戶端的文本信息,包含了服務(wù)器對客戶端請求的響應(yīng)。其基本格式如下:

<HTTP-Version> <Status-Code> <Reason-Phrase>
<Headers>

<Optional Response Body>

其中,各部分的含義如下:

  • <HTTP-Version>:使用的HTTP協(xié)議版本,例如HTTP/1.1。
  • <Status-Code>:一個三位數(shù)的狀態(tài)碼,表示服務(wù)器對請求的處理結(jié)果。
  • <Reason-Phrase>:狀態(tài)碼的文本描述,描述了狀態(tài)碼的原因。
  • <Headers>:包含多行的頭部信息,每行都包含一個頭字段和對應(yīng)的值。
  • <Optional Response Body>:可選的響應(yīng)體,用于包含服務(wù)器返回給客戶端的數(shù)據(jù)。

以下是一個具體的例子:

HTTP/1.1 200 OK
Date: Mon, 15 Nov 2023 12:00:00 GMT
Server: Apache
Content-Type: text/html
Content-Length: 1234
Connection: keep-alive

<html>
  <head>
    <title>Hello, World!</title>
  </head>
  <body>
    <h1>Welcome to my website!</h1>
  </body>
</html>

在這個例子中:

  • 使用的HTTP協(xié)議版本是HTTP/1.1。
  • 狀態(tài)碼是200,表示請求成功。
  • 原因短語是"OK",為狀態(tài)碼的文本描述。
  • 響應(yīng)頭部包含了Date、Server、Content-Type等字段。
  • 由于這是一個簡單的HTML響應(yīng),響應(yīng)體包含了一個HTML文檔。

對于包含響應(yīng)體的響應(yīng),例如HTML頁面、JSON數(shù)據(jù)等,響應(yīng)體會緊隨響應(yīng)頭部,并用一個空行分隔。響應(yīng)體的格式和內(nèi)容取決于服務(wù)器的實際響應(yīng)。

1.4 拓展:GET vs POST 請求方法

GET和POST請求在HTTP中的請求報文和響應(yīng)報文中有一些區(qū)別,這主要涉及到數(shù)據(jù)的傳遞方式和一些特定的語義約定。


GET請求

請求報文:
  1. 參數(shù)傳遞: GET請求的參數(shù)通常附在URL的查詢字符串中,通過?&符號進行連接,例如:http://example.com/resource?param1=value1&param2=value2
  2. 請求體: GET請求通常沒有請求體,因為它用于請求資源,而不是向服務(wù)器提交數(shù)據(jù)。
響應(yīng)報文
  1. 響應(yīng)體: GET請求的響應(yīng)體包含了服務(wù)器返回的資源數(shù)據(jù)。

POST請求

請求報文
  1. 參數(shù)傳遞: POST請求的參數(shù)通常包含在請求體中,而不是在URL中,特別是用于提交表單數(shù)據(jù)或上傳文件等場景。
  2. 請求體: POST請求的請求體包含了客戶端提交給服務(wù)器的數(shù)據(jù)。

響應(yīng)報文
  1. 響應(yīng)體: POST請求的響應(yīng)體包含了服務(wù)器對提交的數(shù)據(jù)的處理結(jié)果。

其他注意事項

  1. 安全性: POST請求的數(shù)據(jù)包含在請求體中,相對于GET請求,POST請求具有更好的安全性,因為它不會在URL中明文傳遞敏感信息。
  2. 冪等性: GET請求是冪等的,多次相同的GET請求應(yīng)該產(chǎn)生相同的結(jié)果。POST請求是非冪等的,多次相同的POST請求可能會產(chǎn)生不同的結(jié)果。

示例:

GET請求示例

請求報文:

GET /resource?param1=value1&param2=value2 HTTP/1.1
Host: example.com

響應(yīng)報文:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234

<!DOCTYPE html>
<html>
  <head>
    <title>GET Response</title>
  </head>
  <body>
    <h1>This is the response to a GET request.</h1>
  </body>
</html>

POST請求示例

請求報文:

POST /submit-form HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 27

param1=value1&param2=value2

響應(yīng)報文:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 45

{"status": "success", "message": "POST response"}

總的來說,GET和POST請求的區(qū)別主要在于參數(shù)傳遞的方式、請求體的內(nèi)容和請求的語義。GET適用于獲取資源,而POST適用于向服務(wù)器提交數(shù)據(jù)。

2 實戰(zhàn)

2.1 QtNetwork模塊介紹

QtNetwork模塊是Qt中用于網(wǎng)絡(luò)編程的模塊,提供了一系列用于處理網(wǎng)絡(luò)通信的類和工具。以下是QtNetwork模塊的一些主要功能:

  1. TCP和UDP通信: 提供QTcpSocketQUdpSocket等類,用于實現(xiàn)TCP和UDP協(xié)議的通信。這些類使得在Qt應(yīng)用程序中創(chuàng)建和管理網(wǎng)絡(luò)連接變得相對簡單。

  2. HTTP客戶端和服務(wù)器: 提供QNetworkAccessManager類,用于實現(xiàn)HTTP協(xié)議的客戶端功能。它支持GET、POST等HTTP請求方法,并允許異步地發(fā)送和接收HTTP請求。

  3. 網(wǎng)絡(luò)請求和響應(yīng)處理: 提供QNetworkRequestQNetworkReply等類,用于構(gòu)建和處理網(wǎng)絡(luò)請求。這些類提供了豐富的功能,包括請求頭的設(shè)置、數(shù)據(jù)的傳輸和響應(yīng)的處理等。

  4. FTP客戶端: 提供QFtp類,用于實現(xiàn)FTP協(xié)議的客戶端功能。它允許在Qt應(yīng)用程序中進行文件傳輸操作。

  5. 網(wǎng)絡(luò)代理: 支持網(wǎng)絡(luò)代理設(shè)置,可以通過QNetworkProxy類配置網(wǎng)絡(luò)代理,以便在需要時通過代理服務(wù)器進行網(wǎng)絡(luò)通信。

  6. 網(wǎng)絡(luò)協(xié)議支持: QtNetwork模塊支持各種網(wǎng)絡(luò)協(xié)議,包括IPv4和IPv6,SSL/TLS等。這使得Qt應(yīng)用程序能夠適應(yīng)多種網(wǎng)絡(luò)環(huán)境和安全需求。

  7. 網(wǎng)絡(luò)狀態(tài)監(jiān)控: 提供QNetworkConfigurationQNetworkConfigurationManager類,用于監(jiān)控和管理網(wǎng)絡(luò)配置,以便在應(yīng)用程序中適應(yīng)不同的網(wǎng)絡(luò)狀態(tài)。

  8. 網(wǎng)絡(luò)緩存: 提供QNetworkDiskCache等類,用于實現(xiàn)網(wǎng)絡(luò)緩存,以提高應(yīng)用程序的性能并減少對網(wǎng)絡(luò)資源的依賴。

這些功能使QtNetwork成為一個強大的網(wǎng)絡(luò)編程工具,適用于開發(fā)涉及網(wǎng)絡(luò)通信的各種應(yīng)用,從簡單的客戶端到復(fù)雜的服務(wù)器應(yīng)用。

2.2 編程實現(xiàn)HTTP客戶端

根據(jù)上述描述,可以知道,使用 QTcpSocketQUdpSocketQNetworkAccessManager、QNetworkRequestQNetworkReply等類可以實現(xiàn)簡單的HTTP客戶端。

  1. (本實例只是制作了一個簡單的 HTTP 客戶端,并不能持久的連接 HTTP 服務(wù)器。類似于瀏覽器給服務(wù)器發(fā)出HTTP請求)接下來是代碼:
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QDebug>
#include <QUrlQuery>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 創(chuàng)建網(wǎng)絡(luò)訪問管理器
    QNetworkAccessManager manager;

    // 創(chuàng)建HTTP請求
    QNetworkRequest getRequest(QUrl("http://example.com"));

    // 發(fā)送GET請求
    QNetworkReply *getReply = manager.get(getRequest);

    // 處理GET請求完成的信號
    QObject::connect(getReply, &QNetworkReply::finished, [&]() {
        if (getReply->error() == QNetworkReply::NoError) {
            qDebug() << "GET Response:" << getReply->readAll();
        } else {
            qDebug() << "GET Error:" << getReply->errorString();
        }

        getReply->deleteLater();
    });

    // 進入應(yīng)用程序事件循環(huán)
    return a.exec();
}

在使用 Qt 進行網(wǎng)絡(luò)請求時,尤其是在進行異步的網(wǎng)絡(luò)操作時,需要進入應(yīng)用程序的事件循環(huán)。這是因為 Qt 的事件循環(huán)負責(zé)處理事件,而網(wǎng)絡(luò)請求的完成(比如接收到服務(wù)器的響應(yīng))通常是通過 Qt 的信號-槽機制來處理的。

讓我們來詳細解釋一下:

  1. 異步操作: Qt 的網(wǎng)絡(luò)操作通常是異步的,即在發(fā)起網(wǎng)絡(luò)請求后,程序會繼續(xù)執(zhí)行后續(xù)的代碼而不等待請求完成。這是為了確保應(yīng)用程序的界面和其他部分能夠保持響應(yīng)性,不被阻塞。

  2. 信號-槽機制: 當(dāng)網(wǎng)絡(luò)請求完成時,QNetworkReply 會發(fā)出 finished 信號。你在代碼中使用 QObject::connect 來連接這個信號到一個槽函數(shù),以便在請求完成時執(zhí)行一些操作。

  3. 事件循環(huán): 為了讓信號-槽機制正常工作,需要進入應(yīng)用程序的事件循環(huán)。調(diào)用 QCoreApplication::exec() 或者 QEventLoop::exec() 啟動事件循環(huán),使得 Qt 可以不斷地檢查并處理事件隊列。

在代碼中,調(diào)用 return a.exec(); 啟動了事件循環(huán)。這樣,當(dāng) GET 請求完成并發(fā)出 finished 信號時,相關(guān)的槽函數(shù)將會被執(zhí)行。如果沒有進入事件循環(huán),這個槽函數(shù)將不會被觸發(fā),因為事件循環(huán)負責(zé)調(diào)度信號的處理。

簡而言之,進入應(yīng)用程序的事件循環(huán)是確保異步操作和信號-槽機制正常工作的關(guān)鍵步驟。如果你的應(yīng)用程序沒有事件循環(huán),它將無法及時響應(yīng)和處理異步操作的完成事件。

  1. 示例2:使用TCP Socket制作一個 HTTP 客戶端
    基本功能:連接服務(wù)器、發(fā)送請求報文、接受響應(yīng)報文

.h文件代碼:

// httpclient.h
#ifndef HTTPCLIENT_H
#define HTTPCLIENT_H

#include <QTcpSocket>
#include <QObject>

class HttpClient : public QObject
{
    Q_OBJECT

public:
	// 構(gòu)造函數(shù)
    explicit HttpClient(QObject *parent = nullptr);

public slots:
	// 連接服務(wù)器
    void connectToServer();

private slots:
	// 讀取服務(wù)器響應(yīng)報文槽函數(shù)
    void readServerResponse();

private:
	// 服務(wù)器Socket
    QTcpSocket *tcpSocket;
};

#endif // HTTPCLIENT_H

.cpp文件代碼:

// httpclient.cpp
#include "httpclient.h"

HttpClient::HttpClient(QObject *parent)
    : QObject(parent)
{
    tcpSocket = new QTcpSocket(this);

    connect(tcpSocket, &QTcpSocket::connected, this, &HttpClient::readServerResponse);
}

void HttpClient::connectToServer()
{
    tcpSocket->connectToHost("127.0.0.1", 8080);
}

void HttpClient::readServerResponse()
{
    QByteArray response = tcpSocket->readAll();
    qDebug() << "Received response:\n" << response;

    tcpSocket->close();
}

2.3 編程實現(xiàn)HTTP服務(wù)器

QNetworkAccessManager 主要用于客戶端,用于處理發(fā)起 HTTP 請求。對于服務(wù)器端,通常需要使用 QTcpServerQTcpSocket 等類來監(jiān)聽連接并處理請求。在下面的例子中,我將演示如何使用 QTcpServer 處理簡單的 HTTP GETPOST 請求。

下面的是使用 QT 的 Tcp Socket 實現(xiàn)的 HTTP 服務(wù)器功能,HTTP 協(xié)議是基于 Tcp 協(xié)議實現(xiàn)的,所以 HTTP 通信的本質(zhì)還是 C/S 之間進行 Tcp Socket 通信。通過字節(jié)流的方式發(fā)送和接受數(shù)據(jù)。無非就是 HTTP 發(fā)送的是 HTTP 格式的請求報文響應(yīng)報文。所以在 Tcp 層次也就是網(wǎng)絡(luò)層次接受到的是報文的字節(jié)流數(shù)據(jù)。HTTP服務(wù)器只需要對接受到的請求報文進行解析即可。

因為請求報文的格式是統(tǒng)一的規(guī)范大家都遵守,所以讀取傳輸數(shù)據(jù)的第一行數(shù)據(jù)的第一個字符串即可知道使用的請求方法是GET、POST等。然后根據(jù)不同的請求方法,寫好不同的處理函數(shù)即可。并寫好對應(yīng)格式的響應(yīng)報文即可。
當(dāng)然我們也可以使用

#ifndef MYHTTPSERVER_H
#define MYHTTPSERVER_H

#include <QTcpServer>
#include <QTcpSocket>
#include <QUrlQuery>
#include <QDebug>

class MyHTTPServer : public QTcpServer
{
    Q_OBJECT

public:
    MyHTTPServer(QObject *parent = nullptr) : QTcpServer(parent) {}

protected:
    //--------------------------------------
    // 說明:這是 QTcpServer 類的虛函數(shù),當(dāng)有新的連接到達時,會被調(diào)用。
    // 日期:2023-11-15
    // 作者:海碼007
    //--------------------------------------
    void incomingConnection(qintptr socketDescriptor) override
    {
        QTcpSocket *socket = new QTcpSocket(this);
        socket->setSocketDescriptor(socketDescriptor);

        // 讀取客戶端請求
        connect(socket, &QTcpSocket::readyRead, [&]() {
            QByteArray requestData = socket->readAll();
            processRequest(requestData, socket);

            // 關(guān)閉連接
            socket->disconnectFromHost();
        });

        // 處理連接斷開
        connect(socket, &QTcpSocket::disconnected, [&]() {
            socket->deleteLater();
        });
    }

private:
    //--------------------------------------
    // 說明:這個函數(shù)用于解析 HTTP 請求,分析請求的方法和路徑,并調(diào)用相應(yīng)的處理函數(shù)。
    // 日期:2023-11-15
    // 作者:海碼007
    //--------------------------------------
    void processRequest(const QByteArray &requestData, QTcpSocket *socket)
    {
        // 解析請求
        QString requestString = QString::fromUtf8(requestData);
        QStringList requestLines = requestString.split("\r\n");

        // 解析第一行,獲取請求方法和路徑
        QString firstLine = requestLines.first();
        QStringList parts = firstLine.split(" ");
        QString method = parts.value(0);
        QString path = parts.value(1);

        // 處理 GET 請求
        if (method == "GET")
        {
            handleGetRequest(path, socket);
        }
        // 處理 POST 請求
        else if (method == "POST")
        {
            handlePostRequest(path, requestData, socket);
        }
    }

    //--------------------------------------
    // 說明:處理 HTTP GET 請求的具體邏輯。
    // 日期:2023-11-15
    // 作者:海碼007
    //--------------------------------------
    void handleGetRequest(const QString &path, QTcpSocket *socket)
    {
        QTextStream responseStream(socket);
        responseStream.setAutoDetectUnicode(true);

        // 構(gòu)造HTTP響應(yīng)
        responseStream << "HTTP/1.1 200 OK\r\n"
                       << "Content-Type: text/html\r\n"
                       << "Connection: close\r\n"
                       << "\r\n"
                       << "<html><body><h1>Hello, World! (GET)</h1></body></html>";

        // 刷新并等待數(shù)據(jù)發(fā)送完畢
        socket->flush();
        socket->waitForBytesWritten();
    }

    //--------------------------------------
    // 說明:處理 HTTP POST 請求的具體邏輯。
    // 日期:2023-11-15
    // 作者:海碼007
    //--------------------------------------
    void handlePostRequest(const QString &path, const QByteArray &requestData, QTcpSocket *socket)
    {
        // 解析 POST 數(shù)據(jù)
        QUrlQuery postData(requestData);
        QString value = postData.queryItemValue("key");

        QTextStream responseStream(socket);
        responseStream.setAutoDetectUnicode(true);

        // 構(gòu)造HTTP響應(yīng)
        responseStream << "HTTP/1.1 200 OK\r\n"
                       << "Content-Type: text/html\r\n"
                       << "Connection: close\r\n"
                       << "\r\n"
                       << "<html><body><h1>Hello, " << value << "! (POST)</h1></body></html>";

        // 刷新并等待數(shù)據(jù)發(fā)送完畢
        socket->flush();
        socket->waitForBytesWritten();
    }
};

#endif // MYHTTPSERVER_H


擴展:另一個簡單示例
.h文件示例:

// httpserver.h
#ifndef HTTPSERVER_H
#define HTTPSERVER_H

#include <QTcpServer>
#include <QTcpSocket>
#include <QObject>

class HttpServer : public QTcpServer
{
    Q_OBJECT

public:
	// 構(gòu)造函數(shù)
    explicit HttpServer(QObject *parent = nullptr);

protected:
	// 當(dāng)有客戶端連接到本服務(wù)器時執(zhí)行的函數(shù),這個函數(shù)是父類的函數(shù),需要重寫
    void incomingConnection(qintptr socketDescriptor) override;

private slots:
	// 讀取客戶端發(fā)送的請求報文
    void readClient();

private:
	// 給客戶端發(fā)送響應(yīng)報文
    void sendResponse(QTcpSocket *clientSocket, const QByteArray &response);
};

#endif // HTTPSERVER_H

cpp文件示例:文章來源地址http://www.zghlxwxcb.cn/news/detail-775624.html

// httpserver.cpp
#include "httpserver.h"

HttpServer::HttpServer(QObject *parent)
    : QTcpServer(parent)
{
}

void HttpServer::incomingConnection(qintptr socketDescriptor)
{
	// 創(chuàng)建一個 connect Socekt 用于存儲客戶端和服務(wù)器的IP和端口,是個四元組數(shù)據(jù)
    QTcpSocket *clientSocket = new QTcpSocket(this);
    clientSocket->setSocketDescriptor(socketDescriptor);

	// 新建一個信號槽連接,當(dāng) connect Socket 準備好數(shù)據(jù)讀取時的信號,與讀取槽函數(shù)連接
    connect(clientSocket, &QTcpSocket::readyRead, this, &HttpServer::readClient);
}

// 讀取客戶端請求報文的槽函數(shù)
void HttpServer::readClient()
{
	// sender()函數(shù)返回的指針是信號發(fā)送者的指針
    QTcpSocket *clientSocket = qobject_cast<QTcpSocket *>(sender());
    if (!clientSocket)
        return;

	// 發(fā)送的請求報文存儲在 connect Socket 中直接讀取即可。數(shù)據(jù)是以字節(jié)流的方式傳輸,如果要正確打印,需要進行解碼
    QByteArray requestData = clientSocket->readAll();
    qDebug() << "Received request:\n" << requestData;

    // 構(gòu)造HTTP響應(yīng)
    QByteArray response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello, World!";
    // 通過 connect Socket給客戶端發(fā)送響應(yīng)報文
    sendResponse(clientSocket, response);

    clientSocket->close();
}

void HttpServer::sendResponse(QTcpSocket *clientSocket, const QByteArray &response)
{
    clientSocket->write(response);
}

到了這里,關(guān)于【QT HTTP】使用QtNetwork模塊制作基于HTTP請求的C/S架構(gòu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Qt 使用HTTP請求網(wǎng)絡(luò)API并接收返回的JSON格式的數(shù)據(jù)

    引入網(wǎng)絡(luò)模塊: mainwindow.h: mainwindow.cpp:

    2024年02月13日
    瀏覽(19)
  • QT之Http請求

    今天我們介紹一下QT的http請求,這里有post和get兩種方式 一、post請求方式:參數(shù)分為網(wǎng)址和具體請求值兩個部分,有時候還需要設(shè)置頭信息,看具體情況定 二、get請求方式:參數(shù)和網(wǎng)址拼接到一起請求 三、主要區(qū)別: get用于請求獲取數(shù)據(jù),post向指定的資源創(chuàng)建修改數(shù)據(jù) g

    2024年02月15日
    瀏覽(23)
  • Python使用POST方法發(fā)送HTTP請求的15個示例(基于requests)

    以下是使用 requests 庫調(diào)用HTTP接口進行POST請求的15個示例: 發(fā)送簡單的POST請求: 發(fā)送JSON格式的POST請求: 發(fā)送XML格式的POST請求: 發(fā)送文件的POST請求:

    2024年02月10日
    瀏覽(23)
  • python 模塊requests 發(fā)送 HTTP 請求

    一、簡介 requests 模塊是 python 基于 urllib,采用 Apache2 Licensed 開源協(xié)議的 HTTP 庫。它比 urllib 更加方便,可以節(jié)約我們大量的工作 二、安裝 三、方法 requsts.requst(method, url,headers,cookies,proxies,timeout) method:請求方式;字符串類型 url:請求的地址;字符串類型 params:查詢參數(shù),g

    2024年02月11日
    瀏覽(24)
  • QT-發(fā)送HTTP請求/QNetworkAccessManager

    注意,如果想使用本文相關(guān)的類,需要在項目的 .pro 文件加入網(wǎng)絡(luò)模塊,也就是需要加入下面一行代碼 本文使用QT發(fā)送一個媒體類型為application/json的post請求,步驟如下: 1.首先創(chuàng)建一個QNetworkAccessManager類,并設(shè)置url和請求參數(shù) 2.發(fā)送請求,發(fā)送之后會返回一個QNetworkReply對象

    2024年02月02日
    瀏覽(16)
  • Nodejs基礎(chǔ)6之HTTP模塊的獲取請求行和請求頭、獲取請求體、獲取請求路徑和查詢字符串、http請求練習(xí)、設(shè)置HTTP響應(yīng)報文、http響應(yīng)練習(xí)

    Nodejs基礎(chǔ)6之HTTP模塊的獲取請求行和請求頭、獲取請求體、獲取請求路徑和查詢字符串、http請求練習(xí)、設(shè)置HTTP響應(yīng)報文、http響應(yīng)練習(xí)

    含義 語法 重點掌握 請求方法 request.method * 請求版本 request.httpVersion 請求路徑 request.url * URL 路徑 require(‘url’).parse(request.url).pathname * URL 查詢字符串 require(‘url’).parse(request.url, true).query * 請求頭 request.headers * 請求體 request.on(‘data’, function(chunk){}),request.on(‘end’, functio

    2024年02月20日
    瀏覽(23)
  • QT進行http請求(post/get)

    在剛接觸QT時第一個任務(wù)就是進行http請求,現(xiàn)在才開始記錄,可能會有遺漏的點。 一、post請求 在.pro文件中 在.h文件中添加對應(yīng)的頭文件 在.cpp中 二、get請求 .pro和.h文件和post請求一樣,在.cpp中

    2024年02月11日
    瀏覽(21)
  • Qt實現(xiàn)HTTP的Get/Post請求

    借助Qt的NetWork模塊,可以輕松的實現(xiàn)HTTP的Get/Post請求,而不需要再次引用像libcurl這樣的第三方庫。 當(dāng)然,Qt的NetWork模塊提供的功能遠遠不只是HTTP方面的。 另外,使用Qt網(wǎng)絡(luò)模塊還需要引用Qt5Network.lib庫。 先構(gòu)造一個QNetworkAccessManager對象,QNetworkAccessManager對象提供了發(fā)送QNe

    2024年02月07日
    瀏覽(21)
  • QT實現(xiàn)客戶端服務(wù)器HTTP(get請求、post請求)

    QT實現(xiàn)客戶端服務(wù)器HTTP(get請求、post請求)

    服務(wù)器代碼如下: QtHttpForS.h QtHttpForS.cpp main.cpp QtHttpForS.ui 客戶端代碼: QtHttpForC.h QtHttpForC.cpp mian.cpp QtHttpForC.ui 程序運行效果: GET請求: POST請求: POST請求使用postman測試: 注意: 可以發(fā)現(xiàn),在使用postman進行POST請求發(fā)送時,服務(wù)器接收到的請求頭與QTSocket的POST請求的請求頭

    2023年04月22日
    瀏覽(23)
  • Node.js-http模塊服務(wù)端請求與響應(yīng)操作,請求報文與響應(yīng)報文

    Node.js-http模塊服務(wù)端請求與響應(yīng)操作,請求報文與響應(yīng)報文

    簡單案例創(chuàng)建HTTP服務(wù)端: 端口號被占用: 1.關(guān)閉當(dāng)前正在運行監(jiān)聽端口的服務(wù) 2.修改其他的端口號 獲取請求方式類型 獲取請求的 url 地址 通過實例化 URl 對象獲取路徑與查詢字符串 獲取 http 協(xié)議的版本號 獲取 http 的請求頭 響應(yīng)報文組成: 1.響應(yīng)行 :包含:HTTP 版本號、響

    2024年02月14日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包