亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Qt如何使用QtWebApp搭建Http服務(wù)器

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

一、QtWebApp源碼下載

a 、下載地址

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

b、 源碼目錄

二、http服務(wù)器搭建

a、使用qt creater新建一個(gè)項(xiàng)目

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

c、新建一個(gè)httpServer的類,繼承stefanfrings::HttpRequestHandler

需要包含相關(guān)頭文件

#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為配置文件內(nèi)容如下:

[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 為文件的根目錄

三、啟動(dòng)http服務(wù)器

在mainwindow中新建一個(gè)HttpServer 變量,然后實(shí)例化,

此時(shí)http服務(wù)器已經(jīng)啟動(dòng)了。

四、獲取http服務(wù)器文件

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

b、我的程序中只實(shí)現(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服務(wù)器的詳細(xì)內(nèi)容,更多關(guān)于Qt QtWebApp搭建Http服務(wù)器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言scandir函數(shù)獲取文件夾內(nèi)容的實(shí)現(xiàn)

    C語言scandir函數(shù)獲取文件夾內(nèi)容的實(shí)現(xiàn)

    scandir?函數(shù)用于列舉指定目錄下的文件列表,本文主要介紹了C語言scandir函數(shù)獲取文件夾內(nèi)容的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • MFC框架之OnIdle案例詳解

    MFC框架之OnIdle案例詳解

    這篇文章主要介紹了MFC框架之OnIdle案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C語言如何計(jì)算字符串長(zhǎng)度

    C語言如何計(jì)算字符串長(zhǎng)度

    這篇文章主要介紹了C語言如何計(jì)算字符串長(zhǎng)度問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C++?Boost?weak_ptr智能指針超詳細(xì)講解

    C++?Boost?weak_ptr智能指針超詳細(xì)講解

    智能指針是一種像指針的C++對(duì)象,但它能夠在對(duì)象不使用的時(shí)候自己銷毀掉。雖然STL提供了auto_ptr,但是由于不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應(yīng)用最為廣泛的一個(gè)
    2022-11-11
  • C++中檢查vector是否包含給定元素的幾種方式詳解

    C++中檢查vector是否包含給定元素的幾種方式詳解

    這篇文章主要介紹了C++中檢查vector是否包含給定元素的幾種方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • C++實(shí)現(xiàn)LeetCode(228.總結(jié)區(qū)間)

    C++實(shí)現(xiàn)LeetCode(228.總結(jié)區(qū)間)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(228.總結(jié)區(qū)間),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++11中l(wèi)onglong超長(zhǎng)整型和nullptr初始化空指針

    C++11中l(wèi)onglong超長(zhǎng)整型和nullptr初始化空指針

    本文介紹?C++11?標(biāo)準(zhǔn)中新添加的?long?long?超長(zhǎng)整型和?nullptr?初始化空指針,在?C++11?標(biāo)準(zhǔn)下,相比?NULL?和?0,使用?nullptr?初始化空指針可以令我們編寫的程序更加健壯,本文結(jié)合示例代碼給大家詳細(xì)講解,需要的朋友跟隨小編一起看看吧
    2022-12-12
  • Microsoft?Visual?C++進(jìn)行調(diào)試的方法實(shí)現(xiàn)

    Microsoft?Visual?C++進(jìn)行調(diào)試的方法實(shí)現(xiàn)

    VS功能極其強(qiáng)大,使用極其便利,本文主要介紹了Microsoft?Visual?C++進(jìn)行調(diào)試的方法實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • C/CPP運(yùn)算優(yōu)先級(jí)的坑及解決

    C/CPP運(yùn)算優(yōu)先級(jí)的坑及解決

    這篇文章主要介紹了C/CPP運(yùn)算優(yōu)先級(jí)的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C++報(bào)錯(cuò) XX does not name a type;field `XX’ has incomplete type的解決方案

    C++報(bào)錯(cuò) XX does not name a type;

    這篇文章主要給大家介紹了C++報(bào)錯(cuò) XX does not name a type;field `XX’ has incomplete type解決方案,文中通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下
    2023-08-08

最新評(píng)論