0

I wrote my QTcpServer based on this post. The socket inserts the total bytes of the QByteArray on the first 4 bytes (qint32). Everything looks fine

Server:

static inline QByteArray IntToArray(qint32 source);

QByteArray IntToArray(qint32 source) {
   QByteArray temp;
   QDataStream data(&temp, QIODevice::ReadWrite);   
   data << source;
   return temp;
}

void multisocket::write_socket(const QJsonObject &obj){
   QJsonDocument doc(obj);
   QByteArray array(doc.toJson());
   qint32 size = array.size();
   qDebug() << "sending..." << size << array.size();

  QByteArray total = IntToArray(size);
  socket->write(total);
  socket->write(array);
  qDebug() << socket->waitForBytesWritten();
}

Server Output:

write_socket sending... 22299 22299
write_socket true

Client:

On the client, I make a loop and verify the total size. Proceed receiving until the total is arrived:

static inline qint32 ArrayToInt(QByteArray source);

void network_controller::read_all_buffer(){
QByteArray buffer;

qint32 size = 0;

while (s->bytesAvailable() > 0)
{
    buffer.append(s->readAll());

    while ((size == 0 && buffer.size() >= 4) ||
           (size > 0 && buffer.size() >= size)){

        if (size == 0 && buffer.size() >= 4)
        {
            size = ArrayToInt(buffer.mid(0, 4));
            buffer.remove(0, 4);
        }

        if (size > 0 && buffer.size() >= size)
        {
           QByteArray data = buffer.mid(0, size);
           QJsonObject obj = socket_ba_to_json(data);
           emit network_callback(obj);
        }
    }
  }

}

The problem: On the client, the size of the first bytes seems ok. I received 22299 from the server and the client, but the loop don't stop and the buffer size increase. What I'm missing?

Client output:

read_all_buffer Receiving:  22299 1460
read_all_buffer Receiving:  538976288 8760
read_all_buffer Receiving:  538976288 4380
read_all_buffer Receiving:  808192544 1460
read_all_buffer Receiving:  538976288 2920
read_all_buffer Receiving:  1381979713 3323
Diego Desenvolvedor
  • 378
  • 1
  • 6
  • 22

2 Answers2

1

THE SOLUTION:

Apparently is something about the scope. Moving the size and the buffer to the header and clear after data is completed resolved the problem.

The header:

private:
 void write_socket(QJsonObject obj);
 QByteArray buffer;
 qint32 size;

Source:

void network_controller::read_all_buffer()
{
   while (s->bytesAvailable() > 0)
   {

     buffer.append(s->readAll());

      while ((size == 0 && buffer.size() >= 4) ||
           (size > 0 && buffer.size() >= size))
      {
        if (size == 0 && buffer.size() >= 4)
        {
            size = ArrayToInt(buffer.mid(0, 4));
            buffer.remove(0, 4);
        }

        if (size > 0 && buffer.size() >= size)
        {
           QByteArray data = buffer.mid(0, size);

           QJsonObject obj = socket_ba_to_json(data);
           size = 0;
           buffer = QByteArray();
           emit network_callback(obj);
        }           
    }
}

}

Diego Desenvolvedor
  • 378
  • 1
  • 6
  • 22
0

It looks like read_all_buffer is called several times for one answer of the server. Try to move buffer and size into fields of network_controller and clean it after emit network_callback.

olya
  • 312
  • 1
  • 4