最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Qt如何使用QtWebApp搭建Http服務器

 更新時間:2024年12月30日 10:47:19   作者:小灰灰搞電子  
這篇文章主要為大家詳細介紹了Qt如何使用QtWebApp搭建Http服務器,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

一、QtWebApp源碼下載

a 、下載地址

http://www.stefanfrings.de/qtwebapp/QtWebApp.zip

b、 源碼目錄

二、http服務器搭建

a、使用qt creater新建一個項目

b、將QtWebApp的源碼拷貝到工程中

c、新建一個httpServer的類,繼承stefanfrings::HttpRequestHandler

需要包含相關頭文件

#include <QObject>
#include "httpserver/httprequesthandler.h"
#include <QSettings>
#include "httpserver/httplistener.h"	//新增代碼
#include "httpserver/httprequesthandler.h"	//新增代碼
#include "httpserver/staticfilecontroller.h"
#include "httpserver.h"
#include <QFile>
#include <QFileInfo>

httpServer.h

#ifndef HTTPSERVER_H
#define HTTPSERVER_H

#include <QObject>
#include "httpserver/httprequesthandler.h"
#include <QSettings>
#include "httpserver/httplistener.h"	//新增代碼
#include "httpserver/httprequesthandler.h"	//新增代碼
#include "httpserver/staticfilecontroller.h"
#include "httpserver.h"
#include <QFile>
#include <QFileInfo>

class HttpServer : public stefanfrings::HttpRequestHandler
{
    Q_OBJECT
public:
    explicit HttpServer(QObject *parent = nullptr);
    void service(stefanfrings::HttpRequest& request, stefanfrings::HttpResponse& response);

    /** Encoding of text files */
    QString encoding;

    /** Root directory of documents */
    QString docroot;

    /** Maximum age of files in the browser cache */
    int maxAge;

    struct CacheEntry {
        QByteArray document;
        qint64 created;
        QByteArray filename;
    };

    /** Timeout for each cached file */
    int cacheTimeout;

    /** Maximum size of files in cache, larger files are not cached */
    int maxCachedFileSize;

    /** Cache storage */
    QCache<QString,CacheEntry> cache;

    /** Used to synchronize cache access for threads */
    QMutex mutex;
};

#endif // HTTPSERVER_H

httpServer.cpp

#include "httpserver.h"

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

    QString configFileName=":/new/prefix1/webapp.ini";
    QSettings* listenerSettings=new QSettings(configFileName, QSettings::IniFormat, this);
    listenerSettings->beginGroup("listener");	//新增代碼

    new stefanfrings::HttpListener(listenerSettings, this, this);	//新增代碼

    docroot = "E:/Qt/learning/httpServer/HttpServer";
}

void HttpServer::service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response)
{
    QByteArray path=request.getPath();
    // Check if we have the file in cache
    qint64 now=QDateTime::currentMSecsSinceEpoch();
    mutex.lock();
    CacheEntry* entry=cache.object(path);
    if (entry && (cacheTimeout==0 || entry->created>now-cacheTimeout))
    {
        QByteArray document=entry->document; //copy the cached document, because other threads may destroy the cached entry immediately after mutex unlock.
        QByteArray filename=entry->filename;
        mutex.unlock();
        qDebug("StaticFileController: Cache hit for %s",path.data());
        response.setHeader("Content-Type", "application/x-zip-compressed");
        response.setHeader("Cache-Control","max-age="+QByteArray::number(maxAge/1000));
        response.write(document,true);
    }
    else
    {
        mutex.unlock();
        // The file is not in cache.
        qDebug("StaticFileController: Cache miss for %s",path.data());
        // Forbid access to files outside the docroot directory
        if (path.contains("/.."))
        {
            qWarning("StaticFileController: detected forbidden characters in path %s",path.data());
            response.setStatus(403,"forbidden");
            response.write("403 forbidden",true);
            return;
        }
        // If the filename is a directory, append index.html.
        if (QFileInfo(docroot+path).isDir())
        {
            response.setStatus(404,"not found");
            response.write("404 not found",true);
            return;
        }
        // Try to open the file
        QFile file(docroot+path);
        qDebug("StaticFileController: Open file %s",qPrintable(file.fileName()));
        if (file.open(QIODevice::ReadOnly))
        {
            response.setHeader("Content-Type", "application/x-zip-compressed");
            response.setHeader("Cache-Control","max-age="+QByteArray::number(maxAge/1000));
            response.setHeader("Content-Length",QByteArray::number(file.size()));
            if (file.size()<=maxCachedFileSize)
            {
                // Return the file content and store it also in the cache
                entry=new CacheEntry();
                while (!file.atEnd() && !file.error())
                {
                    QByteArray buffer=file.read(65536);
                    response.write(buffer);
                    entry->document.append(buffer);
                }
                entry->created=now;
                entry->filename=path;
                mutex.lock();
                cache.insert(request.getPath(),entry,entry->document.size());
                mutex.unlock();
            }
            else
            {
                // Return the file content, do not store in cache
                while (!file.atEnd() && !file.error())
                {
                    response.write(file.read(65536));
                }
            }
            file.close();
        }
        else {
            if (file.exists())
            {
                qWarning("StaticFileController: Cannot open existing file %s for reading",qPrintable(file.fileName()));
                response.setStatus(403,"forbidden");
                response.write("403 forbidden",true);
            }
            else
            {
                response.setStatus(404,"not found");
                response.write("404 not found",true);
            }
        }
    }

}

程序中

    QString configFileName=":/new/prefix1/webapp.ini";
    QSettings* listenerSettings=new QSettings(configFileName, QSettings::IniFormat, this);
    listenerSettings->beginGroup("listener");	//新增代碼

    new stefanfrings::HttpListener(listenerSettings, this, this);	//新增代碼

    docroot = "E:/Qt/learning/httpServer/HttpServer";

configFileName為配置文件內容如下:

[listener]
;host=127.0.0.1
port=8080
minThreads=4
maxThreads=100
cleanupInterval=60000
readTimeout=60000
maxRequestSize=16000
maxMultiPartSize=10000000

[docroot]
path=E:/Qt/learning/httpServer/HttpServer
encoding=UTF-8
maxAge=60000
cacheTime=60000
cacheSize=1000000
maxCachedFileSize=65536

docroot 為文件的根目錄

三、啟動http服務器

在mainwindow中新建一個HttpServer 變量,然后實例化,

此時http服務器已經啟動了。

四、獲取http服務器文件

a、打開瀏覽器輸入http://localhost:8080/filename就能下載到文件名為filename的文件了。

b、我的程序中只實現(xiàn)了zip文件,如果是其他類型文件需要修改一下地方

void StaticFileController::setContentType(const QString fileName, HttpResponse &response) const
{
    if (fileName.endsWith(".png"))
    {
        response.setHeader("Content-Type", "image/png");
    }
    else if (fileName.endsWith(".jpg"))
    {
        response.setHeader("Content-Type", "image/jpeg");
    }
    else if (fileName.endsWith(".gif"))
    {
        response.setHeader("Content-Type", "image/gif");
    }
    else if (fileName.endsWith(".pdf"))
    {
        response.setHeader("Content-Type", "application/pdf");
    }
    else if (fileName.endsWith(".txt"))
    {
        response.setHeader("Content-Type", qPrintable("text/plain; charset="+encoding));
    }
    else if (fileName.endsWith(".html") || fileName.endsWith(".htm"))
    {
        response.setHeader("Content-Type", qPrintable("text/html; charset="+encoding));
    }
    else if (fileName.endsWith(".css"))
    {
        response.setHeader("Content-Type", "text/css");
    }
    else if (fileName.endsWith(".js"))
    {
        response.setHeader("Content-Type", "text/javascript");
    }
    else if (fileName.endsWith(".svg"))
    {
        response.setHeader("Content-Type", "image/svg+xml");
    }
    else if (fileName.endsWith(".woff"))
    {
        response.setHeader("Content-Type", "font/woff");
    }
    else if (fileName.endsWith(".woff2"))
    {
        response.setHeader("Content-Type", "font/woff2");
    }
    else if (fileName.endsWith(".ttf"))
    {
        response.setHeader("Content-Type", "application/x-font-ttf");
    }
    else if (fileName.endsWith(".eot"))
    {
        response.setHeader("Content-Type", "application/vnd.ms-fontobject");
    }
    else if (fileName.endsWith(".otf"))
    {
        response.setHeader("Content-Type", "application/font-otf");
    }
    else if (fileName.endsWith(".json"))
    {
        response.setHeader("Content-Type", "application/json");
    }
    else if (fileName.endsWith(".xml"))
    {
        response.setHeader("Content-Type", "text/xml");
    }
    // Todo: add all of your content types
    else
    {
        qDebug("StaticFileController: unknown MIME type for filename '%s'", qPrintable(fileName));
    }
}

c、下載的源碼中有官方的例程可供參考

以上就是詳解Qt如何使用QtWebApp搭建Http服務器的詳細內容,更多關于Qt QtWebApp搭建Http服務器的資料請關注腳本之家其它相關文章!

相關文章

  • Qt實現(xiàn)將qsqlite數(shù)據(jù)庫中的數(shù)據(jù)導出為Excel表格

    Qt實現(xiàn)將qsqlite數(shù)據(jù)庫中的數(shù)據(jù)導出為Excel表格

    這篇文章主要為大家詳細介紹了如何通過Qt實現(xiàn)將qsqlite數(shù)據(jù)庫中的數(shù)據(jù)導出為Excel表格,文中的示例代碼簡潔易懂,有需要的小伙伴可以了解一下
    2024-12-12
  • C++中關于=default和=delete問題

    C++中關于=default和=delete問題

    這篇文章主要介紹了C++中關于=default和=delete問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • C語言線性表順序表示及實現(xiàn)

    C語言線性表順序表示及實現(xiàn)

    這篇文章主要介紹了C語言線性表順序表示及實現(xiàn),線性表是最常用且最簡單的一種數(shù)據(jù)結構。簡而言之,一個線性表是n個數(shù)據(jù)元素的有限序列
    2022-07-07
  • C語言使用DP動態(tài)規(guī)劃思想解最大K乘積與乘積最大問題

    C語言使用DP動態(tài)規(guī)劃思想解最大K乘積與乘積最大問題

    Dynamic Programming動態(tài)規(guī)劃方法采用最優(yōu)原則來建立用于計算最優(yōu)解的遞歸式,并且考察每個最優(yōu)決策序列中是否包含一個最優(yōu)子序列,這里我們就來展示C語言使用DP動態(tài)規(guī)劃思想解最大K乘積與乘積最大問題
    2016-06-06
  • Java3D實例之創(chuàng)建空間幾何模型的實現(xiàn)方法

    Java3D實例之創(chuàng)建空間幾何模型的實現(xiàn)方法

    本篇文章是對Java3D 創(chuàng)建空間幾何模型的實現(xiàn)方法進行了詳細的介紹。需要的朋友參考下
    2013-05-05
  • c++ signal實現(xiàn)發(fā)送信號

    c++ signal實現(xiàn)發(fā)送信號

    這篇文章主要為大家詳細介紹了c++ signal實現(xiàn)發(fā)送信號的相關知識,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-01-01
  • C語言的動態(tài)內存分配及動態(tài)內存分配函數(shù)詳解

    C語言的動態(tài)內存分配及動態(tài)內存分配函數(shù)詳解

    這篇文章主要為大家詳細介紹了C語言的動態(tài)內存分配及動態(tài)內存分配函數(shù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++聲明extern變量和extern函數(shù)的用法

    C++聲明extern變量和extern函數(shù)的用法

    extern關鍵字可以用來聲明變量和函數(shù)作為外部變量或者外部函數(shù)供其它文件使用,所以本文給大家介紹了C++聲明extern變量和extern函數(shù)的用法,文中有相關的代碼示例供大家參考,需要的朋友可以參考下
    2024-11-11
  • C語言中程序如何調用Python腳本

    C語言中程序如何調用Python腳本

    由于python有很多功能強大的開源庫,有時候在寫C語言程序的時候又想利用一下python強大的模塊,那么C語言中程序如何調用Python腳本,感興趣的小伙伴們可以參考一下
    2021-05-05
  • Visual?Studio?2022下載安裝與使用超詳細教程

    Visual?Studio?2022下載安裝與使用超詳細教程

    這篇文章主要介紹了Visual?Studio?2022最新版安裝與使用教程,本文以社區(qū)版為例通過圖文并茂的形式給大家介紹Visual?Studio?2022安裝使用,需要的朋友可以參考下
    2022-04-04

最新評論

和田市| 黄冈市| 增城市| 新丰县| 贵南县| 都安| 石狮市| 嘉祥县| 宜春市| 昌黎县| 灵石县| 长顺县| 姜堰市| 渑池县| 射洪县| 江阴市| 福州市| 从江县| 曲阳县| 会同县| 张掖市| 年辖:市辖区| 苏尼特左旗| 望谟县| 黄龙县| 乌审旗| 隆回县| 乌什县| 会东县| 天峻县| 定日县| 沙雅县| 临泽县| 兖州市| 江山市| 海兴县| 独山县| 卢氏县| 萨嘎县| 长海县| 贞丰县|