QNetworkReply error "Unable to write"
-
wrote on 4 May 2023, 09:52 last edited by
Greetings to you all
Am trying to upload some file to a remote server using some api (Baidu Net Disk) but i keep getting QNetworkReply::UnknownNetworkError as the error and "Unable to write" as the error string.
This only happens when uploading a file greater than 4MBs ..but for small files (~ 1 mb) everything is fine.
Am using QHttpMultiPart and QHttpPart to upload the file.First off is there some way i can get a more details error message than just Unable to write .
QString formatedMd5; // fileChunkSize holds the content of the file divided into segments ..each segment is 4mb or less foreach (auto hash, mFileChuncks) { if (hash != mFileChuncks.last()) { formatedMd5.append(QString("\"%1\",").arg( QCryptographicHash::hash((hash), QCryptographicHash::Md5).toHex())); } else { formatedMd5.append(QString("\"%1\"").arg( QCryptographicHash::hash((hash), QCryptographicHash::Md5).toHex())); } } qDebug() << "formated md5 " << formatedMd5; QString targetData = QString("path=/%1&isdir=0&autoinit=1&rtype=3&block_list=[%2]&size=%3") .arg(remotePath) .arg(formatedMd5) .arg(file->size()); qDebug() << " target data is" << targetData; QNetworkRequest request(QString("http://pan.baidu.com/rest/2.0/xpan/" "file?method=precreate&access_token=%1") .arg(access_token)); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); request.setRawHeader(QByteArray("X-LC-Session"), QString("4yj8b1l5kvo9wiww2st6jdjn3").toUtf8()); QNetworkReply *mReply = networkManager->post(request, targetData.toUtf8()); if (mReply) { connect(mReply, &QNetworkReply::finished, this, [=]() { this->finished(mReply); }); } }
This works well when uploading small files, but fails when uploading larger files....please help me!
-
Greetings to you all
Am trying to upload some file to a remote server using some api (Baidu Net Disk) but i keep getting QNetworkReply::UnknownNetworkError as the error and "Unable to write" as the error string.
This only happens when uploading a file greater than 4MBs ..but for small files (~ 1 mb) everything is fine.
Am using QHttpMultiPart and QHttpPart to upload the file.First off is there some way i can get a more details error message than just Unable to write .
QString formatedMd5; // fileChunkSize holds the content of the file divided into segments ..each segment is 4mb or less foreach (auto hash, mFileChuncks) { if (hash != mFileChuncks.last()) { formatedMd5.append(QString("\"%1\",").arg( QCryptographicHash::hash((hash), QCryptographicHash::Md5).toHex())); } else { formatedMd5.append(QString("\"%1\"").arg( QCryptographicHash::hash((hash), QCryptographicHash::Md5).toHex())); } } qDebug() << "formated md5 " << formatedMd5; QString targetData = QString("path=/%1&isdir=0&autoinit=1&rtype=3&block_list=[%2]&size=%3") .arg(remotePath) .arg(formatedMd5) .arg(file->size()); qDebug() << " target data is" << targetData; QNetworkRequest request(QString("http://pan.baidu.com/rest/2.0/xpan/" "file?method=precreate&access_token=%1") .arg(access_token)); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); request.setRawHeader(QByteArray("X-LC-Session"), QString("4yj8b1l5kvo9wiww2st6jdjn3").toUtf8()); QNetworkReply *mReply = networkManager->post(request, targetData.toUtf8()); if (mReply) { connect(mReply, &QNetworkReply::finished, this, [=]() { this->finished(mReply); }); } }
This works well when uploading small files, but fails when uploading larger files....please help me!
wrote on 4 May 2023, 11:26 last edited by JonB 5 Apr 2023, 11:38@Sheep
First make sure that your server accepts >4MB, and acrossQHttpMultiPart
.You might read the long recent thread https://forum.qt.io/topic/143988/using-qhttpmultipart-to-send-big-files-via-http-freezes-my-applicatio and see how they claim it works.
First off is there some way i can get a more details error message than just Unable to write .
I don't think so, Qt has reported all it can. You know it is (supposedly) not one of the other errors in https://doc.qt.io/qt-6/qnetworkreply.html#NetworkError-enum. I guess it might be something has gone wrong with >4MB, or maybe that is the error you get if the server closes the connection during client writing, I don't know. You could take a chance at looking at errno, hoping it's left from whatever Qt did to cause the write error, maybe you'll get e.g.
ECONNABORTED
,ENOTCONN
,EPIPE
, or GetLastError() code under Windows. -
@Sheep
First make sure that your server accepts >4MB, and acrossQHttpMultiPart
.You might read the long recent thread https://forum.qt.io/topic/143988/using-qhttpmultipart-to-send-big-files-via-http-freezes-my-applicatio and see how they claim it works.
First off is there some way i can get a more details error message than just Unable to write .
I don't think so, Qt has reported all it can. You know it is (supposedly) not one of the other errors in https://doc.qt.io/qt-6/qnetworkreply.html#NetworkError-enum. I guess it might be something has gone wrong with >4MB, or maybe that is the error you get if the server closes the connection during client writing, I don't know. You could take a chance at looking at errno, hoping it's left from whatever Qt did to cause the write error, maybe you'll get e.g.
ECONNABORTED
,ENOTCONN
,EPIPE
, or GetLastError() code under Windows.wrote on 4 May 2023, 13:00 last edited byI tried using Wireshark to track the the network packets but I noticed something like " new fragment overlaps old data"....then qt reports the " unable to write" error!..
-
I tried using Wireshark to track the the network packets but I noticed something like " new fragment overlaps old data"....then qt reports the " unable to write" error!..
wrote on 4 May 2023, 13:46 last edited byAm using QHttpMultiPart and QHttpPart to upload the file.
Call me stupid, but where in the code?
QNetworkReply *mReply = networkManager->post(request, targetData.toUtf8());
Don't you have to call
QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, QHttpMultiPart *multiPart)
rather than
QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, const QByteArray &data)
? Or are you saying the Qt code does this for you (I don't know)?You should perhaps also
connect()
toQNetworkReply::errorOccurred()
especially given your situation.Ah, I think I might actually have a hunch! You send
QString targetData
local variable as thepost(const QByteArray &data)
. I wonder if it's continually reading from this after the reply is established? Thepost(QIODevice *data)
overload tells you the file must remain open for reading, and I guess theconst QByteArray &data
parameter may imply the same. Try making yourtargetData
persist (new
or class variable) till theQNetworkReply::finished()
signal is received. -
wrote on 5 May 2023, 05:25 last edited by
@JonB ..am really sorry i posted the wrong code..
The API has three stages of uploading the files...and the code i initially was the preparation stage... that`s why i used the QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, const QByteArray &data) ..am really sorry about that..But here the code for uploading the files
// chuckIterator is a QList<QByteArray>::iterator class member variable pointing to member a QList<QByteArray> class member // Since the api requires to divide any files greater than 4mb into segments of 4mb (depending on the files size) if (!chuckIterator.hasNext()) { return; } QByteArray data_ = chuckIterator.next(); int partSequence = mFileChuncks.indexOf(data_); qDebug() << "running part sequence " << partSequence; QString url = QString("https://d.pcs.baidu.com/rest/2.0/pcs/" "superfile2?access_token=%1&method=upload&type=tmpfile&" "path=/%2&uploadid=%3&partseq=%4") .arg(access_token) .arg(remotePath) .arg(mUploadId) .arg(partSequence); qDebug() << "Request Url " << url; auto path = localPath; QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); QFileInfo info(path); QString fileName = info.fileName(); QHttpPart filePart; filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("file/*")); filePart.setHeader( QNetworkRequest::ContentDispositionHeader, QVariant(QString("form-data; " "name=\"file\";fieldname=\"chapter\";filename=\"%1\"") .arg(fileName))); filePart.setHeader(QNetworkRequest::ContentLengthHeader,data_.size()); filePart.setBody(data_); file->setParent(multiPart); multiPart->append(filePart); QNetworkRequest request(url); QNetworkReply *mReply = networkManager->post(request, multiPart); if (mReply) { connect(mReply, &QNetworkReply::finished, this, [=]() { this->finished(mReply); }); }
1/5