Qt QNetworkAccessManager为什么我不能在同一主线程中并行发送多个http请求
Qt QNetworkAccessManager why i can’t send more then 1 http request in parallel in the same main thread
我刚刚注意到,当我尝试发送http请求,而已经有http请求在后台进行,其中一个停止等待,直到前一个结束。它们都使用自己的qnetworkaccessmanager。有人能解释一下为什么会这样吗?
我一定是在这里做错了什么我不知道,这里有一些代码。
有两个HTTP post函数,第一个是简单的post,每5秒调用一次第二个是并行调用的文件上传post函数。
当我调用文件上传的第一个停止,直到文件上传完成,并继续这是来自Qt与我的干预。这是使用单个QNetworkAccessManager
//Init in the class contractor
networkManager = new QNetworkAccessManager(this);
connect(networkManager,SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), this, SLOT(on_sslErr(QNetworkReply*,QList<QSslError>)));
//-----------------------------------------------------\
//this is upload file code , its taking time untill it finish working great
PostImageRequest( QString& Response,
QMap<QString,QString> paramsToPostMap,
QString& BaseUrl,
QString imageFullPath,
int iTimeOutInterval)
QByteArray imageFormat = QImageReader::imageFormat(imageFullPath);
QString imageMimeType(imageFormat);
QNetworkRequest request;
QUrl params;
QMapIterator<QString,QString> i(paramsToPostMap);
while (i.hasNext()) {
i.next();
addField(i.key(),i.value());
}
addFile("file",imageFullPath,imageMimeType);
QString crlf="rn";
qsrand(QDateTime::currentDateTime().toTime_t());
QString b=QVariant(qrand()).toString()+QVariant(qrand()).toString()+QVariant(qrand()).toString();
QString boundary="---------------------------"+b;
QString endBoundary=crlf+"--"+boundary+"--"+crlf;
QString contentType="multipart/form-data; boundary="+boundary;
boundary="--"+boundary+crlf;
QByteArray bond=boundary.toAscii();
QByteArray send;
bool first=true;
for (int i=0; i<fieldNames.size(); i++) {
send.append(bond);
if (first) {
boundary=crlf+boundary;
bond=boundary.toAscii();
first=false;
}
send.append(QString("Content-Disposition: form-data; name=""+fieldNames.at(i)+"""+crlf).toAscii());
if (encodingS=="utf-8") send.append(QString("Content-Transfer-Encoding: 8bit"+crlf).toAscii());
send.append(crlf.toAscii());
send.append(strToEnc(fieldValues.at(i)));
}
for (int i=0; i<files.size(); i++) {
send.append(bond);
send.append(QString("Content-Disposition: form-data; name=""+fileFieldNames.at(i)+""; filename=""+fileNames.at(i)+"""+crlf).toAscii());
send.append(QString("Content-Type: "+fileMimes.at(i)+crlf+crlf).toAscii());
send.append(files.at(i));
}
send.append(endBoundary.toAscii());
fieldNames.clear();
fieldValues.clear();
fileFieldNames.clear();
fileNames.clear();
fileMimes.clear();
files.clear();
request.setHeader(QNetworkRequest::ContentTypeHeader, contentType.toAscii());
request.setHeader(QNetworkRequest::ContentLengthHeader, QVariant(send.size()).toString());
request.setUrl(BaseUrl);
if(iTimeOutInterval != -1)
{
QEventLoop loop2;
QTimer::singleShot(iTimeOutInterval, &loop2, SLOT(quit()) );
loop2.exec();
}
QEventLoop loop;
QNetworkReply *reply = networkManager->post(request,send);
connect(reply, SIGNAL(uploadProgress(qint64,qint64)), this,SLOT(SetProgress(qint64,qint64)));
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
//return response
QNetworkReply::NetworkError networkError = reply->error();
HandleNetworkError(networkError);
Response.clear();
QByteArray data=reply->readAll();
Response.append(data);
//delete reply;
reply->deleteLater();
//--------------------------------------------------------------------------------\
//this is the post function that invoket every 5 secound
PostRequest(QString& Response,
QMap<QString,QString> paramsToPostMap,
QString& BaseUrl,
int iTimeOutInterval)
QNetworkRequest request;
QUrl params;
QMapIterator<QString,QString> i(paramsToPostMap);
while (i.hasNext()) {
i.next();
params.addQueryItem(i.key(),i.value());
}
request.setUrl(BaseUrl);
QByteArray postArgs;
postArgs = params.encodedQuery();
if(iTimeOutInterval != -1)
{
QEventLoop loop2;
QTimer::singleShot(iTimeOutInterval, &loop2, SLOT(quit()) );
loop2.exec();
}
QEventLoop loop;
QNetworkReply *reply = networkManager->post(request,postArgs);
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
//return response
QNetworkReply::NetworkError networkError = reply->error();
HandleNetworkError(networkError);
Response.clear();
QByteArray data=reply->readAll();
Response.append(data);
//delete reply;
reply->deleteLater();
来自Qt 4.7参考:
QNetworkAccessManager对它接收到的请求进行排队。并行执行的请求数量取决于协议。目前,对于桌面平台上的HTTP协议,一个主机/端口组合并行执行6个请求。
相关文章:
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 如何在boost beast http请求中设置http头
- 发送一个带有libcurl C++问题的帖子请求:s
- C++17中的并行执行策略
- 在多个核心中处理一个HTTP请求
- 并行用于C++17中数组索引范围内的循环
- 如何在Elixir中调用递归函数并行
- OpenMP:并行更新数组总是需要减少数组吗
- 如何使用OpenMP并行这两个循环
- 如何使用OpenMP并行化此矩阵时间矢量运算
- 如何使用OpenMP使这个循环并行
- 遍历并行数组以确定C++中的最大数字
- 为什么 openmp 的并行不适用于矢量化色彩空间转换?
- 如何在 Mac 上使用 c++17 并行标准库算法?
- 查询时间/周期是针对所有内核/线程的序列化请求还是并行请求?
- 是否需要多个 OpenSSL 生物对象来允许并行请求?
- 进行并行libcurl HTTP请求
- 如何在一个套接字上实现并行请求和响应的非阻塞客户端-服务器通信模型,而不存在数据竞争
- Qt QNetworkAccessManager为什么我不能在同一主线程中并行发送多个http请求
- 对于客户端服务器程序,并行接收多个客户端连接请求的最佳方法是什么