开发者

How to transfer larger objects through a socket in QT?

开发者 https://www.devze.com 2023-03-03 19:24 出处:网络
I would like to send/recieve image files and 2 ints as messages in a client server program. I\'m using QLocalSocket and QImage for this.

I would like to send/recieve image files and 2 ints as messages in a client server program.

I'm using QLocalSocket and QImage for this.

However I don't know how to read from the socket only after the image and the integers are fully written to the buffer, since the readyRead signal is already fired after the first couple of bytes.

Here's parts of my code:

// sending
QDataStream stream(socket);
stream << image << i << j;


// recieving
void MainWindow::readyRead() {
    // ...
    if (socket->bytesAvailable() > 400)
    {
        QByteArray b = socket->readAll();
        QDataStream stream(&b, QIODevice::ReadOnly);

        QImage image;
        int i, j;
        stream >> image >> i >> j;
    // ...
    }
}

I tried guessing the incoming file size, but since QImage is serialized to PNG the data size is variable and sometimes the end of the file doesn't get written to the buffer before I start t开发者_开发问答o read it.

Is there an easy solution to this?


I would send a fixed size header first that describes the data being sent, specifically the type and size in bytes.

Then as you receive readReady events you pull whatever data is available into a buffer. Once you determine you have received all of the necessary data, you can stream it into a QImage object.


The BMP format has size information and PNG format has size information for each chunk. These are formats with what QImage serializes.

If you don't want to extract the information from raw data then serialize QImage first to QBuffer (so you know/control size and format better). Then stream that size and buffer.


Code example:

QBuffer buffer;
image.save(&buffer, "PNG", 100); //can change the compression level to suit the application - see http://qt-project.org/doc/qt-4.8/qimage.html#save
qint64 length = sizeof(quint32) + buffer.data().size(); //http://doc.qt.digia.com/4.7/datastreamformat.html
stream << length;
stream << buffer.data();

Then on the other end, first stream out the qint64 length so you know how big socket->bytesAvailable() has to be to stream out the full QByteArray. Then:

QByteArray ba;
stream >> ba;
QImage image = QImage::fromData(ba); // Get image from buffer data
0

精彩评论

暂无评论...
验证码 换一张
取 消