目录
一、gitHub地址
二、功能
三、目前存在的问题
四、界面效果
五、主要代码
开发过程中遇到了一些坑,花了半天时间搞。出现了很多理论上不应该出现的bug。
做这个的目的,主要是为了巩固一下对Qt网络部分接口的使用。
思路主要是,解析URL——>获取响应头——>获取响应状态码——>请求下载——>回读当前文件字节数进行断点续传。
需要注意,访问https前,需要添加libcrypto-1_1.dll与libssl-1_1.dll到Qt\5.14.0\mingw73_32\bin或者exe目录下。
下载地址:http://slproweb.com/products/Win32OpenSSL.html
需要注意一下32位和64位,应下载与自己Qt编译器位数一致的版本。下载好后直接安装,然后到安装目录拷贝即可。
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 = "<head(request);
m_state = requestHead;
getCurrentFileSize();
connect(m_reply,SIGNAL(finished()),this,SLOT(onfinishedRequest()));
}
}
暂停下载:
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;
}
}
槽函数onfinishedRequest():
void Http::onfinishedRequest()
{
if(m_reply==nullptr) return;
if(m_state == requestHead)
{
m_fileSize = m_reply->rawHeader("Content-Length").toInt();
qDebug()<<"m_fileSize = "<get(request);
loop->exec();
//获取状态码
m_statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug()<<"statusCode="<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)));
}
槽函数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();
}
}