Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QJsonDocument (QJsonArray) sent through network



  • Hey all, I've got a problem.
    I've sent the QByteArray/QString representation of a QJsonDocument through the network.
    The receiving endpoint has received it correctly (dumped the contents to a QPlainTextEdit to check), but when I try to reconstruct the QJsonArray contained in the document, I get no error but no array either (size == 0)
    The code I'm using is:

    QJsonParseError *error = nullptr;
    QJsonDocument documento = QJsonDocument::fromJson(buffer,error);
    if (error)
    {
    	ui->pteRegistro->setPlainText("ERROR JSON:"+error->errorString());
    	return;
    }
    QJsonObject obj = documento.object();
    QJsonArray arr = obj.value("Personas").toArray(); // arr.size() == 0 ?
    
    

    What am I missing?
    The structure of the JSON passed data is:
    {
    "Personas":[
    { ...}, {...}
    ]
    }



  • @linuxkid you may want to check that the JSON you're sending is a valid one with this tool...



  • @linuxkid Hi, you may missing a parsing error because your error condition is always false.

    QJsonParseError error;
    QJsonDocument documento = QJsonDocument::fromJson(buffer, &error);
    if (error.error != QJsonParseError::NoError){
        ui->pteRegistro->setPlainText("ERROR JSON:"+error.errorString());
        return;
    }
    


  • @Pablo-J.-Rogina said in QJsonDocument (QJsonArray) sent through network:

    @linuxkid you may want to check that the JSON you're sending is a valid one with this tool...

    Yup, it says its valid json in green, also it was generated client-side with QJsonDocument from a QJsonObject that is a QJsonArray..
    The exact output is the one that is used in the receiving endpoint..



  • @Gojir4 said in QJsonDocument (QJsonArray) sent through network:

    @linuxkid Hi, you may missing a parsing error because your error condition will always be false.

    QJsonParseError error;
    QJsonDocument documento = QJsonDocument::fromJson(buffer, &error);
    if (error.error != QJsonParseError::NoError){
        ui->pteRegistro->setPlainText("ERROR JSON:"+error.errorString());
        return;
    }
    

    Whoops, you're right.
    errorString() says JSON:illegal value..
    However I've checked sent data and output and both pass the JSONLint validator..


  • Lifetime Qt Champion

    QJsonParseError also has an offset parameter which helps you where to look exactly.
    And are you sure buffer has the complete data? How to you read it from the socket?


  • Moderators

    @linuxkid said in QJsonDocument (QJsonArray) sent through network:

    I've sent the QByteArray/QString representation of a QJsonDocument through the network.

    First things first: Print the raw QByteArray that you received over the network. What do you see?



  • Hey guys, so yeah..
    After carefully analyzing the offsets I did manage to see a difference..
    Apparently, I've got problems on some boundaries where there are some special characters..
    So, I ended up instead of sending the whole JSON Array, send item per item.
    Since they're small (50bytes) it seems there is no issue.

    It might be some part of the logic I applied for receiving chunks of 1000bytes each, and the way I'm appending one chunk to the other in the receiving buffer.
    However, right now I've reached a functional point, of which I'm not the proudest person about.. So I'm marking the problem as solved..


  • Lifetime Qt Champion

    You have to put all into a QByteArray and only convert it to a QString when all arrived.



  • @Christian-Ehrlicher said in QJsonDocument (QJsonArray) sent through network:

    You have to put all into a QByteArray and only convert it to a QString when all arrived.

    That was what I was doing, somehow somewhere else in my logic there exists some problem..

    The page boundaries seem to be the ones where the problem occured.

    I've since changed it to accept one object at a time, but the logic was as follows:

    readyRead() -> dataReceived() -> readAll(), append to QByteArray;

    Chunks where sent in 1000bytes fashion, unluckily, it always got cut in some quote/colon and that caused an object to be ill-terminated in the JSON.

    Since then, I deviced a simple protocol, for each array, a Tag was sent with a number wich indicated the ammount of items, then the server would reply Tag:OK to start transmission, then each Tag was followed by chunks of data not superior to 400bytes -not exactly perfect, but certainly smaller than MTU- wich englobed the JSON Object.
    When the server had parsed correctly the object, it would return Tag:Ok again, or Tag:Fail for wrong, and make it resend.
    When the total ammount of Items in the Array was passed and parsed correctly, the server sends Tag:END to notify the client the next JSON object (wich maps to a class) can be sent, even single-objects where an array of one, and then parsed server-side..

    Not that it matters, because I'm not entirely pleased with the "protocol", nor its speed, nor my inability at the time to fix the other code, but I document it just in case someone else wants to take in the idea.. It did end up serving me well..

    Regards,


Log in to reply