Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QNetworkReply error "Unable to write"
Forum Updated to NodeBB v4.3 + New Features

QNetworkReply error "Unable to write"

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 2 Posters 746 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SheepS Offline
    SheepS Offline
    Sheep
    wrote on last edited by
    #1

    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!

    JonBJ 1 Reply Last reply
    0
    • SheepS Sheep

      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!

      JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by JonB
      #2

      @Sheep
      First make sure that your server accepts >4MB, and across QHttpMultiPart.

      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.

      SheepS 1 Reply Last reply
      0
      • JonBJ JonB

        @Sheep
        First make sure that your server accepts >4MB, and across QHttpMultiPart.

        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.

        SheepS Offline
        SheepS Offline
        Sheep
        wrote on last edited by
        #3

        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!..

        JonBJ 1 Reply Last reply
        0
        • SheepS Sheep

          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!..

          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by
          #4

          @Sheep

          Am 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() to QNetworkReply::errorOccurred() especially given your situation.

          Ah, I think I might actually have a hunch! You send QString targetData local variable as the post(const QByteArray &data). I wonder if it's continually reading from this after the reply is established? The post(QIODevice *data) overload tells you the file must remain open for reading, and I guess the const QByteArray &data parameter may imply the same. Try making your targetData persist (new or class variable) till the QNetworkReply::finished() signal is received.

          1 Reply Last reply
          0
          • SheepS Offline
            SheepS Offline
            Sheep
            wrote on last edited by
            #5

            @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 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved