PDA

View Full Version : 'Garbage at the end of the document' error on parsing QJsonDocument



ms2222
25th December 2015, 09:38
i want to sending json object over tcp socket and, i serializing the json object like this :


void message_shooter::send_packet(QJsonObject packet)
{
QJsonDocument json_doc(packet);
//QByteArray packet_bytes=json_doc.toBinaryData();
QByteArray packet_bytes=json_doc.toJson();
m_client_socket->write(packet_bytes);
m_client_socket->waitForBytesWritten();
m_client_socket->flush();
qDebug()<<"Byte Written!";
}

and i reading data like this :

void connectivity_layer::on_socket_ready_read()
{
qDebug()<<"Ready read...";
qint64 incomming_packet_size=m_socket->bytesAvailable();
if (incomming_packet_size > 0)
{
QByteArray received_bytes=m_socket->read(incomming_packet_size);
m_buffer.append(received_bytes);

m_buffer.simplified();
QJsonParseError parse_error;
QJsonDocument json_doc=QJsonDocument::fromJson(m_buffer,&parse_error);

if (parse_error.error == QJsonParseError::NoError)
{
QJsonObject i_packet=json_doc.object();
m_buffer.clear();
analys_packet(i_packet);

}
else
{
qDebug()<<"Error!";
qDebug()<<QString::fromUtf8(m_buffer);
qDebug()<<parse_error.errorString();
}
}
}

But this doesn't work and print 'Garbage at the end of the document' error! [when the data received completely]
how can i solve this problem?

anda_skoa
25th December 2015, 12:47
It is usually bad idea to not have the message length as part of the protocol.

In your case you have to re-attempt parsing even if the message is not complete yet.
What's even worse, if you parse a message you are clearing the buffer, throwing away any data for the next message that you have already received.

So if you want to make this something robust, first transmit the length of the serialized JSON block, then the block itself.
On the receiver side, first read the length, then as many bytes as necessary before attempting parsing and then keep all remaining available data for the next round.

Cheers,
_

P.S.: QByteArray::simplified() is const. And a very bad idea anyway to call on an input buffer.

Cheers,
_