Qt实现 Http网络在线下载程序(支持断点续传功能)

C++多线程断点续传下载器:从原理到工程实现 多线程编程是现代软件开发中提升性能的核心技术,其原理在于通过并发执行任务来充分利用多核CPU资源。在C++中,通过std::thread、线程池等机制可以实现高效的并发控制。断点续传则是网络传输领域的关键技术,它基于HTTP协议的Range头部,允许从特定字节位置恢复下载,极大提升了大文件传输的可靠性。结合多线程与断点续传,可以构建高性能、高可靠的下载工具,这在**大文件下载**和**不稳定网络环境**等场景下价值显著。本文将以一个支持多线程并发下载与断点续传的C++文件下载器为例,深入剖析其系统架构、线程 阅读详情

目录

一、gitHub地址

二、功能

三、目前存在的问题

四、界面效果

五、主要代码


开发过程中遇到了一些坑,花了半天时间搞。出现了很多理论上不应该出现的bug。

做这个的目的,主要是为了巩固一下对Qt网络部分接口的使用,以及http协议的记忆。

思路主要是,解析URL——>获取响应头——>获取响应状态码——>请求下载——>回读当前文件字节数进行断点续传。

需要注意,访问https前,需要添加libcrypto-1_1.dll与libssl-1_1.dll到Qt\5.14.0\mingw73_32\bin或者exe目录下。

以上DLL下载地址:http://slproweb.com/products/Win32OpenSSL.html

需要注意一下32位和64位,应下载与自己Qt编译器位数一致的版本。下载好后直接安装,然后到安装目录拷贝即可。

一、gitHub地址

https://github.com/KindMans/HttpDownLoad

 

二、功能

支持输入url网址进行在线下载,具备断点续传功能。

后期扩展:结合qml树列表与多线程,模拟出迅雷的下载效果。

 

三、目前存在的问题

QEventLoop *loop = new QEventLoop;
connect(m_netWorkManager, SIGNAL(finished(QNetworkReply*)), loop, SLOT(quit()));
m_reply = m_netWorkManager->get(request);
loop->exec();

通过以上get访问到需要跳转的url时,速度明显快于不需要跳转的。具体原因还不清楚。

 

四、界面效果

粗略的绘制了一下界面,比较丑,主要以实现效果为主。

 

五、主要代码

启动下载:

void Http::startDownLoad(const QString &url)
{
    m_url = url;
    if(m_url.isEmpty()) return;

    if(!m_IsDownloading)
    {
        //获取请求头
        QNetworkRequest request;
        QUrl url = QUrl(m_url);
        request.setUrl(url);
        m_fileName = url.fileName();
        qDebug()<<"fileName = "<<m_fileName;
        m_reply = m_netWorkManager->head(request);
        m_state = requestHead;
        getCurrentFileSize();
        connect(m_reply,SIGNAL(finished()),this,SLOT(onfinishedRequest()));
    }
}

通过setUrl来装载我们请求的地址,随后获取请求头,请求结束后,进入槽函数做处理。

暂停下载:

void Http::stopDownLoad()
{
    if(m_reply == nullptr) return;

    disconnect(m_reply,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
    disconnect(m_reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(onError(QNetworkReply::NetworkError)));
    disconnect(m_reply,SIGNAL(finished()),this,SLOT(onfinishedRequest()));

    m_reply->abort();
    m_reply->deleteLater();

    m_file.close();
    getCurrentFileSize();

    m_IsDownloading = false;
}

暂停下载主要是断开信号槽的连接,然后释放资源和关闭文件操作符。

文件大小回读:

void Http::getCurrentFileSize()
{
    QFileInfo fileInfo(m_fileName);
    if(fileInfo.exists())
    {
        m_currentLoadedBytes = fileInfo.size();
    }
    else
    {
        m_currentLoadedBytes = 0;
    }
}

通过QFileInfo类提供的size()接口,获取文件当前的字节大小。

槽函数onfinishedRequest():

void Http::onfinishedRequest()
{
    if(m_reply==nullptr) return;

    if(m_state == requestHead)
    {       
        m_fileSize = m_reply->rawHeader("Content-Length").toInt();
        qDebug()<<"m_fileSize = "<<m_fileSize;
        if(m_currentLoadedBytes == m_fileSize)
        {
            qDebug()<<"文件已经存在!";
            return;
        }

        QEventLoop *loop = new QEventLoop;
        connect(m_netWorkManager, SIGNAL(finished(QNetworkReply*)), loop, SLOT(quit()));
        QNetworkRequest request;
        request.setUrl(m_url);
        m_reply = m_netWorkManager->get(request);
        loop->exec();

        //获取状态码
        m_statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
        qDebug()<<"statusCode="<<m_statusCode;
        m_state = requestBody;
    }

    QNetworkRequest request;
    if(m_statusCode==200)
    {
        request.setUrl(m_url);
    }
    else if(m_statusCode == 302)    //存在转调url
    {
        //获取实际下载地址
        QUrl realUrl = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
        request.setUrl(realUrl);
    }
    else
    {
        return;
    }

    QString downLoadSize = QString::number(m_fileSize);
    QString selectSize = QString("bytes=%1-%2").arg(m_currentLoadedBytes).arg(downLoadSize);
    request.setRawHeader("Range",selectSize.toLatin1());
    m_reply = m_netWorkManager->get(request);

    connect(m_reply,SIGNAL(finished()),this,SLOT(onfinishedRequest()));
    connect(m_reply,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
    connect(m_reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(onError(QNetworkReply::NetworkError)));
}

这里需要注意的是做了一个转调功能,因为有些资源的实际下载地址并不是当前所给的Url。当返回302的时候,说明需要获取背后正确的下载地址。

槽函数onReadyRead():

void Http::onReadyRead()
{
    if(m_reply==nullptr) return;

    if(!m_file.isOpen())
    {
        m_file.setFileName(m_fileName);
        m_file.open(QIODevice::WriteOnly|QIODevice::Append);
    }

    m_file.write(m_reply->readAll());

    m_downLoadedBytes =m_file.size();

    emit fileDownloadProgress(m_downLoadedBytes, m_fileSize);
    if(m_file.size() == m_fileSize)
    {
        qDebug()<<"download finished!";
        stopDownLoad();
    }
}

将接收到的数据,写入文件中,并且将当前下载字节数通过信号槽发送出去,提供给进度条对话框使用。

当下载的字节总大小等于请求时服务器返回过来的文件大小时,就认为下载结束。

当然,更严谨的做法是再计算文件的MD5码,与服务器回传的MD5码进行比较,以确保下载的是正确的文件。

Qt 6.7 在线安装器配置:3步切换国内镜像源,下载速度提升 5 倍 本文详细介绍了如何通过3步配置Qt 6.7国内镜像源,显著提升下载速度至5倍以上。针对Windows用户常见的下载卡顿问题,提供了中科大、清华TUNA等优质镜像源选择,并包含命令行参数配置、验证方法及高级异常处理技巧,是开发者优化Qt安装效率的实用指南。 阅读详情

相关推荐

告别龟速!用Fiddler4+清华镜像,5分钟搞定QT6.1.2在线安装(保姆级教程)

本文提供了一份详细的QT6.1.2在线安装教程,通过使用Fiddler4和清华镜像源,将安装时间从数小时缩短至5分钟。教程涵盖环境准备、Fiddler4配置、组件选择策略及安装后优化设置,帮助开发者高效完成QT6.1.2的安装与配置。

weixin_33690367的博客 502

Qt5(C++)高级篇之1:HTTP网络编程实战

1.带领您深入学习QT5/C++:HTTP基础理论、GET抓取网页、POST提价数据、JSON解析、文本浏览器、图片浏览器,逐步提升Qt编程水平。2.所有章节均有理论知识介绍、接口讲解、实例代码讲解,讲解过程中不断穿插老师在开发过程中遇到的问题及解决方法(可以下载所有的电子课件与源码)。3.本阶段主要完成Qt高阶段的HTTP编程:所有章节均配备实战项目、边理论边实战    1. HTTP基础理论HTTP协议简介HTTP请求流程图HTTP协议概述HTTP工作原理基于 请求-响应 的模式无状态保存无连接HTTP请求方法HTTP状态码URLHTTP请求格式(请求协议)HTTP响应格式(响应协议)HTTP请求正文HTTPS协议简介HTTPS握手过程win10x64安装OpenSSL:不用编译源码什么是OpenSSLOPENSSL“心脏出血”漏洞Nginx作为HTTP服务器Tomcat作为HTTP服务器一、JDK环境变量配置二、Tomcat环境变量配置三、eclipse配置四、创建JSP项目2. Qt实现HTTP编程入门QNetworkAccessManager新建项目新建类配置文件添加network头文件CPP文件3. Qt实现HTTP的GET抓取网页头文件库文件Get4. Qt实现HTTP的GET/POST提交数据5. Qt处理HTTP的JSON解析jsp返回json格式的数据Qt处理jsp返回的Json数据6. Qt实现HTTP文本浏览器7. Qt实现HTTP文件下载器8. Qt实现HTTP图片浏览器9. Qt实现HTTP服务器  

WEB大文件上传解决方案支持分片断点上传

前端:vue2,vue3,vue-cli,html5,webuploader后端:asp.net,jsp,springboot,php,平台:Windows,macOS,Linux,中标麒麟,银河麒麟,统信UOS,信创国产化场景:内网,外网,政府,涉密环境,信创国产化项目数据库:MySQL,Oracle,SQL Server,达梦,人大金仓,国产数据库功能:超大文件上传,文件和文件夹批量上传,断点续传,加密上传,视频上传。

weixin_52041354的博客 1737

Qt 之 HTTP 请求 多线程分块下载——上(获取下载文件大小)

简述在 Qt 之 HTTP 请求下载(支持断点续传) 文章中我们使用Qt 的方法进行HTTP 请求下载文件,同时能够断点续传,本篇文章是这一篇文章的续篇。我们一般在网上下载软件、电影、文件等,大都是使用迅雷下载,因为迅雷下载相对而言较快。在我们日常生活中,使用迅雷下载大文件时,非常占网速,甚至会占用整个家庭局域网的带宽。有时候浏览器都打不开网页,但是迅雷有限速功能,能够保护正常上网。下面看一张图。这

前行之路还需前行 9948

Qt 案例 使用QNetworkReply或者URLDownloadToFile 下载http、https资源到本地路径

Qt 使用QNetworkReply或者URLDownloadToFile两种不同方式下载http、https链接资源文件,并且获取下载进度。

... 2697

Qt 基于http的网络文件下载

1.需要用到的类 QNetworkAccessManager类用于协调网络操作,负责发送网络请求,创建网络响应 QNetworkReply类表示网络请求的响应。在QNetworkAccessManager发送一个网络请求后创建一个网络响应。它提供了以下信号: finished():完成后发出信号 readyRead():有数据读的数据发出信号 downloadProgress():表示网络操作进度的信号,有bytesRead和totalBytes两个参数,表示已读取字节数和总字节数 2.运行界面

希望能帮助大家,希望大家多多支持,你们的支持是我前进的动力。 6049

客户端在线更新-QT

QT客户端在线更新

turbolove的博客 1994

C++ Qt框架开发的程序添加自动更新功能

由于直接替换正在运行的程序文件本身是一个挑战(因为操作系统通常会锁定正在执行的文件),因此需要一些技巧来实现这一目标。多线程下载将一个大的文件分成多个小的块,每个块由一个线程负责下载。当所有线程都完成各自的下载任务后,再将这些小块文件合并成最终的文件。文件分割 :根据文件的大小,将其分割成多个分块(chunks),确定每个分块的起始和结束字节。下载并记录进度 :每个线程在下载时,需要记录当前已下载的字节数,以备后续的断点续传。文件合并 :所有分块下载完成后,需要将分块文件按照顺序合并成完整的文件。

h a 6 6 6 c k 为 你解决复杂难题! 631

Qt封装libcurl文件下载资源库:简化文件下载任务,提升开发效率

Qt封装libcurl文件下载资源库:简化文件下载任务,提升开发效率 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在软件开发领域,文件下载是常见的需求之一。Qt封装libcurl文件下载资源库,正是为了满足这一需求而诞生。这是一个基于Qt5和libcurl库封装的文件下载工具,适用于Windows平台,支持HTTP和FTP协议,具备多线程下载和断点续传功能,旨在帮助...

gitblog_06779的博客 1062

Qt 5.6.2 HTTP下载器项目实战

Qt HttpDownload是一个强大的网络下载工具,主要用于网络编程,特别是涉及到HTTP协议的文件下载操作。它广泛应用于各种需要从网络获取数据的应用程序中,例如浏览器、下载器、在线视频播放器等。Qt HttpDownload支持断点续传、多线程下载等功能,可以大大提高应用程序的网络传输效率和稳定性。Qt网络模块提供了一系列的类和对象,用于处理TCP/IP和UDP网络编程。核心类包括QTcpSocketQUdpSocket, 和等。这些类分别代表了不同的网络功能,如。

weixin_29069575的博客 1098

基于QT5的高效多线程下载器设计与实现

要创建一个独立运行的线程,首先需定义一个类继承自QThread。该类可以封装任意复杂的业务逻辑,如网络请求、数据解析或文件写入等。以下是一个典型的自定义线程类示例:Q_OBJECTpublic:// 安全停止线程的方法protected:// 重写run方法private:// 控制线程退出标志// 标记任务是否完成对应的实现文件如下:m_abort) {// 模拟耗时操作// 可在此处发射进度信号(但注意跨线程连接)// 内建信号,也可自定义wait()

weixin_29476595的博客 1046

QtHTTP多线程断点续传下载v2.0:高效的单文件下载解决方案

QtHTTP多线程断点续传下载v2.0:高效的单文件下载解决方案 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在当前互联网环境中,大文件下载已成为许多用户的日常需求。QtHTTP多线程断点续传下载v2.0项目正是为了解决这一需求而设计。它是一个基于Qt4和Qt5的Http单文件多线程下载工具,不仅支持多线程下载,还具备断点续传功能,大大提高了下载效率和用户体验。 项...

gitblog_06733的博客 774

Qt基于http的全量升级程序,自动下载安装

使用http访问下载最新的软件安装包,通过结束当前进程再自动打开安装包实现全量升级

QT下载器开发实战:用AI 3步构建高效多线程工具

这里要注意HTTP协议中Range头的使用,以及如何确保各线程下载的数据能正确拼接成完整文件。最初直接让各线程并发写文件导致数据错乱,后来改为每个线程先下载到临时文件,最后再合并的方案。建议有类似需求的开发者可以试试这个方案,特别是平台的多线程调试工具对排查下载器这类并发问题很有帮助。特别适合快速验证这类桌面应用,尤其是它的AI辅助和实时预览功能,帮我省去了不少环境配置的麻烦。最近在做一个需要批量下载资源的小工具,发现用现成的下载器总有些功能不顺手,干脆自己动手开发一个QT下载器。

RubyLion28的博客 705

qt 线程池实现多线程下载

使用qt线程池实现多线程http请求,支持限速下载,可以设置全部下载的网络上限,和单个线程的网络上限。可以实时显示当前下载速度。

混合开关电容DCDC变换器技术解析与工程应用指南

在电源设计领域,传统DCDC变换器在高降压比或高升压比场景下,往往面临占空比过窄、开关应力大、效率偏低等瓶颈。开关电容变换器虽能实现固定比例的电压变换,却受限于调节能力。混合开关电容DCDC变换器通过“开关电容网络粗调变比+电感式DCDC细调输出”的策略,兼顾高效率、高功率密度与宽调压范围。本文梳理了其典型拓扑(如2:1/4:1 SC+Buck)、关键对比、控制策略(含软充电)及工程应用中的常见问题,帮助电源工程师在服务器供电、快充、车载电源等场景下快速选型与调试。

weixin_29164185的博客 311

QT下载开发效率提升秘籍

传统开发中需要自行处理网络异常、文件分块等细节,而这里通过封装好的接口,代码量减少60%以上。而在快马平台,这些步骤完全省略——打开网页即可获得预置QT开发环境,直接开始编码,省去至少1-2小时的初始化时间。而平台提供的一键部署功能,自动生成可访问的在线演示链接,无需处理跨平台兼容性。实际体验中,从零开始完成一个基础下载应用,传统方式可能需要2-3天,而通过快马平台仅用3-4小时即可上线。在开发QT下载应用的过程中,传统方式往往需要经历环境配置、界面设计、功能实现、调试部署等多个繁琐步骤,耗时耗力。

ThunderstormLynx23的博客 475

告别Qweb!用ReportBro在Odoo 13-19版本中5步搞定动态报表

本文介绍了如何在Odoo 13-19版本中使用ReportBro替代Qweb快速实现动态报表设计。通过5步集成指南,包括环境准备、前端集成、后端服务搭建等,展示了ReportBro在可视化设计、即时预览和多格式输出(PDF/XLSX)方面的优势,显著提升开发效率和报表灵活性。

mac99的博客 799

三款免费下载工具组合:让HTTP、BT、磁力下载稳定又高效

下载资源时,速度慢、任务中断、磁力链接卡在“获取元数据”等问题,常常被误判为资源失效,实则大多是下载工具与协议不匹配。HTTP直链依赖服务端对Range请求的支持,专业下载管理器通过多线程分段拉取与断点续传,能将系统镜像、软件安装包这类大文件稳定下完;BT种子与磁力链接则遵循P2P机制,需要Tracker服务器和DHT网络找到对等节点,才能高效传输社区分享的公开资源。免费工具兼顾协议覆盖与干净体验,无需开会员即可获得足够好的下载表现。面向日常网页下载、大文件直链、种子资源三类典型场景,Motrix、qBit

weixin_34380948的博客 581

糖果【贪心】

【问题描述】 有N(1≤N <100,000)N(1≤N~<100,000)N(1≤N <100,000)种不同类型的糖果,每种糖果数量无限多。第i种糖果每颗的价格是Pi(1≤Pi≤1018),有Ci(1≤Ci≤1018)P_i(1≤P_i≤10^{18}),有C_i (1≤C_i≤10^{18)}Pi​(1≤Pi​≤1018),有Ci​(1≤Ci​≤1018)头牛想吃这种糖果。 FarmerJohnFarmer JohnFarmerJohn拥有金钱BBB元(1≤B≤1

算法小猪的博客 794

第四次工业革命如何重构产业逻辑:写给技术人的趋势推演

第四次工业革命正在以人工智能、大数据和新能源为核心重构全球产业逻辑。本文从历史规律切入,指出技术革命本质是生产力跃迁和产业链话语权的转移。当前AI基础设施竞赛已形成算力、数据、算法三大支柱,其中算力投资首超石油领域,绿色算力与新型架构成为关键。数据治理带来隐私计算等新技术约束,数据中心正向液冷技术和"东数西算"模式演进。技术人需构建三大竞争力:夯实分布式系统等底层能力、培养跨领域知识融合能力、善用约束条件驱动创新。这场变革将奖励那些深度理解技术本质并能快速适应的实践者。

几十年资深高级架构师,技术专家的技术笔记。专注C、Java、Python、微服务、云原生、AI工程化及高并发系统分布式架构实战,分享源码剖析、性能调优与架构治理经验。 287
上一篇: 批处理之bat脚本删除指定文件外的所有文件与文件夹
下一篇: 基于原生c++代码实现的Http下载程序
Qt上位机开发
Qt上位机开发 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄9年 9664粉丝 178原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值