我想在客户端服务器程序中发送/接收图像文件和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,因此数据大小是可变的,有时在开始读取之前文件的末尾不会写入缓冲区。
有一个简单的解决方案吗?
答案 0 :(得分:3)
我会首先发送一个固定大小的头,描述发送的数据,特别是字节的类型和大小。
然后,当您收到readReady事件时,您将可用的任何数据提取到缓冲区中。一旦确定已收到所有必要数据,就可以将其流式传输到QImage对象中。
答案 1 :(得分:1)
BMP格式具有大小信息,PNG格式具有每个块的大小信息。这些是QImage序列化的格式。
如果您不想从原始数据中提取信息,请先将QImage序列化为QBuffer(这样您就可以更好地控制/控制大小和格式)。然后流式传输该大小和缓冲区。
答案 2 :(得分:1)
代码示例:
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长度,这样你就知道流出完整的QByteArray需要多大socket->bytesAvailable()
。然后:
QByteArray ba;
stream >> ba;
QImage image = QImage::fromData(ba); // Get image from buffer data