Как передать большие объекты через сокет в QT? - PullRequest
1 голос
/ 09 мая 2011

Я хотел бы отправлять / получать файлы изображений и 2 дюйма в виде сообщений в клиент-серверной программе.

Я использую QLocalSocket и QImage для этого.

ОднакоЯ не знаю, как читать из сокета только после того, как изображение и целые числа полностью записаны в буфер, так как сигнал readyRead уже запускается после первой пары байтов.

Вот частимой код:

// 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;
    // ...
    }
}

Я попытался угадать размер входящего файла, но, поскольку QImage сериализован в PNG, размер данных является переменным, и иногда конец файла не записывается в буфер перед началомчитать его.

Есть ли простое решение для этого?

Ответы [ 3 ]

3 голосов
/ 09 мая 2011

Сначала я бы отправил заголовок фиксированного размера, который описывает отправляемые данные, в частности тип и размер в байтах.

Затем, когда вы получаете события readReady, вы извлекаете все доступные данные в буфер. Как только вы определите, что получили все необходимые данные, вы можете передать их в объект QImage.

1 голос
/ 24 мая 2013

Пример кода:

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();

Затем на другом конце сначала вытяните длину qint64, чтобы вы знали, насколько большим socket->bytesAvailable() должен быть поток для полного QByteArray.Тогда:

QByteArray ba;
stream >> ba;
QImage image = QImage::fromData(ba); // Get image from buffer data
1 голос
/ 09 мая 2011

Формат BMP содержит информацию о размере, а формат PNG имеет информацию о размере для каждого чанка.Это форматы, которые сериализует QImage.

Если вы не хотите извлекать информацию из необработанных данных, сначала сериализуйте QImage в QBuffer (чтобы вы лучше знали / управляли размером и форматированием).Затем выполните потоковую передачу этого размера и буфера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...