https内容就不讲了,网上内容很多,也可以观看以前总结下来的内容。
Qt https 配置以及介绍:https://blog.youkuaiyun.com/bloke_come/article/details/103479714
上传思路:
- 为了更加快速上传需要先建一个预读线程
- 制作发送表单
- 如果服务器不支持组包,那么要增加一个变量用来判断是否能发送下一次
具体代码:
// 线程预读部分
QFile file( /*文件路径*/ );
if(!file.open(QIODevice::ReadOnly) || !file.exists())
{
file.close();
m_isOpenSuccess = false;
return;
}
// 获取文件大小,并计算最多是多少块
qint64 iSize = file.size();
m_iChuncks = iSize % g_iChunkSize == 0 ? 0 : 1;
m_iChuncks = (m_SliceInfo.iSize / g_iChunkSize) + iChunks;
while (!file.atEnd())
{
msleep(10);
if(m_isStopUpload)
{
file.close();
return;
}
if(
(-1 == m_iChunckThread) ||
(m_listFileChunck.size() >= 5)
)
{
msleep(50);
continue;
}
// 跳转到需要读几块,光标移动到0的位置目的是为了放置读取错误,基本不耗时
file.seek(0);
file.seek(g_iChunkSize * m_iChunckThread);
QByteArray array = file.read(g_iChunkSize);
++m_iChunckThread;
std::unique_lock<std::mutex> lock(m_mutex);
m_listFileChunck.push_back(array);
}
file.close();
变量解释:
m_isOpenSuccess :打开文件失败标志
g_iChunkSize : 设置的块大小
iChuncks : 总共分了多少块
m_iChunckThread:续传时应该读第几块
m_listFileChunck:已读到的内容存放容器,这里规定不大于5块时才需要继续预读
m_isStopUpload 停止上传
发送表单
QNetworkRequest request;
m_Request.swap(request);
QString qstrURL = ;
m_Request.setUrl(qstrURL);
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
// 告诉服务器总块数
QHttpPart chunksPart;
chunksPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"chunks\""));
chunksPart.setBody(QString::number(m_iChuncks).toStdString().c_str());
multiPart->append(chunksPart);
// 告诉服务器当前是上传第几块
QHttpPart chunkPart;
chunkPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"chunk\""));
chunkPart.setBody(QString::number(iChunck).toStdString().c_str());
multiPart->append(chunkPart);
// 告诉服务器上传文件的文件名称
QHttpPart filePart;
QString qstrFormat = QString("form-data; name=\"file\"; filename=%1;").arg(m_qstrFileName);
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(qstrFormat));
// 取对应的块数
std::unique_lock<std::mutex> lock(m_mutex);
filePart.setBody(m_listFileChunck.front());
m_listFileChunck.erase(m_listFileChunck.begin());
multiPart->append(filePart);
++m_iChunck;
// 发送表单
QNetworkReply *reply = m_AccessManager->post(m_Request, multiPart);
multiPart->setParent(reply);
无法组包情况下,根据返送判断是否继续发送,还是标记为发送失败
// 如果成功继续处理
bool isSuccess = jsonObject["success"].toBool();
if(isSuccess)
{
if(m_iChunck >= m_iChuncks)
{
// 标记为上传完成
}
else
{
// 标记为可以继续发送
m_isCanSendData = true;
// 计算上传进度
m_qstrUploadProgress = QString::number((iChunck / (iChuncks * 1.00)) * 100, 'f', 2);
emit sigUploadProgress(m_qstrUploadProgress );
}
return true;
}
如果失败,标记为上传失败或者其他待处理逻辑