如何在QT中通过套接字传输较大的对象?

发布于 2024-11-06 03:56:35 字数 728 浏览 1 评论 0原文

我想在客户端服务器程序中发送/接收图像文件和 2 个整数作为消息。

我为此使用 QLocalSocketQImage

但是,我不知道如何仅在图像和整数完全写入缓冲区后才从套接字读取数据,因为在前几个字节之后已经触发了 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,数据大小是可变的,有时在我开始读取文件之前,文件末尾不会写入缓冲区。

有一个简单的解决方案吗?

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 to read it.

Is there an easy solution to this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冬天旳寂寞 2024-11-13 03:56:35

我会首先发送一个固定大小的标头来描述正在发送的数据,特别是类型和大小(以字节为单位)。

然后,当您收到 readReady 事件时,您将所有可用数据拉入缓冲区。一旦确定已收到所有必要的数据,您就可以将其流式传输到 QImage 对象中。

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.

墨离汐 2024-11-13 03:56:35

BMP 格式具有每个块的大小信息,PNG 格式具有每个块的大小信息。这些是 QImage 序列化的格式。

如果您不想从原始数据中提取信息,则首先将 QImage 序列化为 QBuffer (以便您更好地了解/控制大小和格式)。然后流式传输该大小和缓冲区。

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.

秋风の叶未落 2024-11-13 03:56:35

代码示例:

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文