Reading Data from QNetworkReply Returns Nothing



  • Hi All,

    I am trying to read and write data using QNetworkReply the peice of code able to send data and could write data to server but I am not able to fetch data from server to local running client;

    Client side code as follows:

    void  PostDataRequest(QString RegName,QString RegAdd,QString EnterData)
    {
    const char* USERAGENT = "Mozilla/Firefox 3.6.12";
    
    QString m_url = "http://" + m_ServerIP + ":" + m_Port;
    
    QUrl myURL(m_url);
    QNetworkRequest request(myURL);
    request.setRawHeader("User-Agent", USERAGENT);
    request.setRawHeader("Content-Type", "application/json");
    QNetworkAccessManager mgr;
    
    QUrlQuery qu;
    qu.addQueryItem("RegName", RegName);
    qu.addQueryItem("RegAdd", RegAdd);
    qu.addQueryItem("EnterData", EnterData);
    qu.addQueryItem("Value", "@@@");
    
    QUrl params;
    params.setQuery(qu);
    
    QNetworkReply *reply = mgr.post(request, params.toEncoded());
    
    QEventLoop eventLoop;
     QObject::connect(&mgr, SIGNAL(finished(QNetworkReply*)), &eventLoop,        SLOT(quit()));
     eventLoop.exec();
    QString str_Recdata = reply->readAll();
    qDebug() << "Success Receive data: " << str_Recdata;
    return str_Recdata;
    } 
    

    Above code is sending data using post but I am not able to get reply from server.

    Where server Code is :

    void readyRead()
    {
    QTcpSocket *socket = static_cast<QTcpSocket*>(sender());
    int BytesAvl(socket->bytesAvailable());
    QByteArray bufferData = QByteArray::fromRawData(socket->readAll(),BytesAvl);
    json::mycounter = bufferData.indexOf(json::srch,0);
    bufferData = bufferData.mid(json::mycounter);
    if(!(bufferData.size() < sizeof(int))){
        if(socket->state() == QAbstractSocket::ConnectedState)
            {
                socket->write(bufferData,1); //write size of data
               // socket->write(bufferData); //write the data itself
                qDebug() <<"Waiting for Byters " << socket->waitForBytesWritten();
                socket->close();
                 if(socket->state() == QAbstractSocket::ConnectedState)
                     qDebug() << "\ntrue";
                 else
                      qDebug() << "\nFalse";
            }
       // int BytesSend(socket->write((const char *)bufferData,bufferData.size()));
       // qDebug() << "BytesSend"<< BytesSend;// << "Connection "<<connected;
        emit dataReceived(bufferData);
      }
     bufferData.clear();
     }
    

    Where QDebug Output is :

    Waiting for Byters true
    False
    DATA "RegName=NA&RegAdd=NA&EnterData=Status&Value=@@@" //Output of Emit Signal
    Success Receive data: "" // NO_DATA_HERE

    Where Byte received is Zero I am stucked help me through this!!!!

    Thanks for Time!!!

    Praveen


  • Moderators

    @praveen0991kr
    check if the reply has an error before reading from it.

    Also i noticed that you close the socket in the server?
    Then you check if the connection state is still connected?
    And you do all this on the readyRead slot, which just tells you that there data to read, but it still may be that there is more data on the socket incoming later on.

    But as i said you are closing the connection on the first data that comes in.
    Also you should call flush() after you are done writing data on the socket, to make sure everything is sent.
    Better use QTcpSocket::disconnectFromHost() which does it implicitly.

    But anyway:

    Since you are using QNetworkAccessManager::post() you receive a HTTP request on the server.
    So you need to implement HTTP parsing in your server. Which means parse all the HEADERS and read the Content-Length. After the header section is fully received you need to read the amount of bytes from the Content-Length header.
    Only then you are finished with reading, can write your reply and can close the connection.

    I am not sure if that's what you want ;)

    Maybe it's better to use QTcpSocket directly rather than QNetworkAccessManager to send the data to the server. Then you can think of your custom format of messages.
    E.g. "<DataSize>|<EncodedData>"
    On the server you reading until you find your delimiter (| in this example). And keep reading until you have read <DataSize> bytes from the socket.



  • Thanks for Reply !!!

    I am able to read data in myReadyRead() and after parsing I got the Data that I have sent from void PostDataRequest(QString RegName,QString RegAdd,QString EnterData) i.e : 47 Bytes as I have mention in code:

    after checking bufferData(QByteArray) I am writing back to same socket but no luck !!!!!
    and disconnecting from host as per your suggestion . Emitting data through required result for that I am sure bufferData that is created is correct.

    Could you pls. ensure the writing steps in socket is correct i.e socket->write() and close steps

    void JsonServer::myreadyRead()
    {
        QTcpSocket *socket = static_cast<QTcpSocket*>(sender());
        int BytesAvl(socket->bytesAvailable());
        QByteArray bufferData = QByteArray::fromRawData(socket->readAll(),BytesAvl);
        json::mycounter = bufferData.indexOf(json::srch,0);    //QByteArray srch("Re");
        bufferData = bufferData.mid(json::mycounter);
        if(!(bufferData.size() < sizeof(int))){
            if(socket->state() == QAbstractSocket::ConnectedState)
                {
                    int BytesWritten = socket->write(bufferData,bufferData.size()); //write size of data
                    qDebug() << BytesWritten;          //47 Bytes are Written
                    socket->disconnectFromHost();
                     emit dataReceived(bufferData);     //BufferData Contain "RegName=NA&RegAdd=NA&EnterData=Status&Value=@@@" after HTTP header 
                    return;
                }   
        }
         bufferData.clear();
    }
    

    QDebug Output :
    47
    DATA: "RegName=NA&RegAdd=NA&EnterData=Status&Value=@@@"
    Success Receive data: ""

    Thanks
    Praveen


  • Moderators

    @praveen0991kr
    did you check if a error is returned in the network reply (on the client side)?



  • After adding this code I got :

    QNetworkReply *reply = mgr.post(request, params.toEncoded());

    QString str_Recdata = reply->errorString();
    qDebug() <<"Error String : "<< str_Recdata;
    QEventLoop eventLoop;
    QObject::connect(&mgr, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
    eventLoop.exec();
    
    qDebug() << "Success Receive data: " << str_Recdata;
    

    Success Receive data: "Unknown error"


  • Moderators

    @praveen0991kr
    of course you should read the error after the reply has finished, not before...



  • I have added some Code : sourcefile.cpp

    QString CRWWebCall::PostDataRequest(QString RegName,QString RegAdd,QString  EnterData)
      {
        const char* USERAGENT = "Mozilla/Firefox 3.6.12";
    
        QString m_url = "http://" + m_ServerIP + ":" + m_Port;
    
        qDebug() << m_url;
    
        //QUrl myURL(QString("http://localhost:8003"));
        QUrl myURL(m_url);
        QNetworkRequest request(myURL);
        request.setRawHeader("User-Agent", USERAGENT);
        request.setRawHeader("Content-Type", "application/json");
    
        QNetworkAccessManager mgr;
    
        QUrlQuery qu;
        qu.addQueryItem("RegName", RegName);
        qu.addQueryItem("RegAdd", RegAdd);
        qu.addQueryItem("EnterData", EnterData);
        qu.addQueryItem("Value", "@@@");
        QUrl params;
        QNetworkReply *reply;
        params.setQuery(qu);
        connect(&mgr, SIGNAL(finished(QNetworkReply *)),
                        this, SLOT(finished(QNetworkReply *)));
    
        connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
                        this,  SLOT(onError(QNetworkReply::NetworkError)));
        reply = mgr.post(request, params.toEncoded());
    
        QString str_Recdata = reply->errorString();
        //qDebug() <<"Error String : "<< str_Recdata;
        QEventLoop eventLoop;
        QObject::connect(&mgr, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
        eventLoop.exec();
    
        qDebug() << "Success Receive data: " << str_Recdata;
    
       return str_Recdata;
    }  
    

    Some Code In header File:

    private slots:
        void finished(QNetworkReply * reply )
        {
            qDebug() << "Bytes"<< reply->bytesAvailable();
            if(reply->error() !=QNetworkReply::NoError)
            {
                QMessageBox::warning(0, QString("NetworkAccessManager NetworkReply"),
                                    QString("QNetworkReply error string: \n") + reply->errorString(),
                                    QMessageBox::Ok);
            }
        }
    
        void onError(QNetworkReply::NetworkError err )
        {
            if(err !=QNetworkReply::NoError)
            {
                QMessageBox::warning(0, QString("Error!"),
                                    QString("Error loading webpage: \n") + QString::number(err),
                                    QMessageBox::Ok);
            }
        }
    

    alt text

    Thanks for Reply !!


  • Moderators

    @praveen0991kr
    damn...thats the drawback of using QNetworkAccessManager with a plain tcp socket.

    Your response also has to be a HTTP response in order to make QNetworkReply work properly.

    E.g.

    HTTP/1.0 200 OK
    Date: Fri, 01 Jan 1970 23:59:59 GMT
    Content-Type: text/html
    Content-Length: 1259
    
    <CONTENT-with-a-size-of-1259-bytes>
    

    So the most important is the first line that says everything was ok. Which is reflected by QNetworkReply's error.
    I would take this as an minimal example for an response, don't know for sure which headers are mandatory.
    Note the empty line between the header and body section! And each line should end with \r\n
    See RFC-2616 for more details.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.