2011-05-09 16 views
1

我想在客户端服务器程序中发送/接收图像文件和2个整数作为消息。如何通过QT中的套接字传输更大的对象?

我使用这个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数据大小是可变的,有时文件的末尾没有得到写入在我开始读取它之前的缓冲区。

有没有简单的解决方案呢?

+1

你能不只是第一次发送图像的大小?例如,在由公共接口定义的报头结构中。你还可以包括其他有用的信息,如发件人标签,时间戳,名称等...... – Dennis 2011-05-09 17:06:38

回答

1

的BMP格式具有尺寸信息和PNG格式具有用于每个块的大小的信息。这些是QImage序列化的格式。

如果你不想提取原始数据中的信息,然后第一序列的QImage到Q缓冲器(所以你知道/控制大小和格式更好)。然后流传输大小和缓冲区。

+0

谢谢,我设法从QBuffer获得对象的大小,现在它可以工作。 – sekmet64 2011-05-10 14:38:58

3

我将发出一个固定大小标头的第一描述正在发送的数据,特别是在字节类型和大小。

然后当你收到你拉什么数据是可用到缓冲区readReady事件。一旦你确定你已经收到了所有必要的数据,你可以将它流入一个QImage对象。

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长度,所以你知道socket->bytesAvailable()有多么大,是流出来的完整的QByteArray。然后:

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