将 QByteArray 反序列化为多个 QVariantMap的
Deserializing QByteArray to multiple QVariantMap's
我正在为IPC使用QTcpSockets。我想我对QTcpSocket readyReady信号发射有一些问题。我发现QTcpSocket缓冲有问题。
在正常情况下,有一段真正简单的代码可以将QByteArray反序列化为QVariantMap
// Init Last Buffer
QByteArray lastBuffer;
// ...
// Init New Data Stream
QDataStream newDataStream(lastBuffer);
// Init Last Data Map
QVariantMap lastDataMap;
// Clear Last Variant Map
lastDataMap.clear();
// Red Data Stream To Data Map
newDataStream >> lastDataMap;
所有的工作都很好,直到我快速发送了很多包裹。事实证明,QTcpSocket将这些封装到更大的封装中。有时我将所有数据接收到一个QByteArray中,有时单独接收到不同大小的包中,这绝对不是在另一端实际写入/发送包的方式。
我的问题是:你们中有人有同样的问题吗?已经有解决方案了吗?你能推荐一个好的解决方案吗?
当然,我可以去挖掘所有相关的Qt源代码,但我的重点是在我的项目中,只要在定制、开发和更改方面投入合理的精力,就可以获得一个简单但足够复杂的解决方案,重用现有的Qt组件。创新;)
谢谢大家!
您的问题是因为TCP是一种流协议,这意味着数据将以不同的块到达您的计算机,并在新块到达时呈现给您的应用程序。QTcpSocket
符合此规范,因此当它发出数据已到达的信号时,不能保证数据是完整的。
不幸的是,QDataStream
假设它正在读取的设备包含一组完整的数据。如果QDataStream
读取的数据用完,它将退出,并返回未定义的结果,它不会等待下一个QVariant
完成下载。
因此,不能像在具有完整数据集的其他设备(如QFile
)上那样在QTcpSocket
上使用QDataStream
。
您需要在程序中构建额外的处理,以检查是否有足够的数据到达进行解析。
如果您查看Fortune Client和Fortune Server示例的文档,您会发现它们首先使用QDataStream
将数据串行化为QByteArray
,然后在通过网络发送时预先设置了数据的大小。
客户端首先等待,直到有足够的数据到达以读取数据流的大小,然后将传入的数据存储在QByteArray
中,直到所有数据都到达,然后将其移交给QDataStream
进行解析。
如果您不是每次都传输大量数据,或者您很高兴有足够的内存资源将数据临时保存在QByteArray
中,直到数据准备好被解析,那么这种方法就很好了。
如果您需要在数据进入时进行解析,建议您创建自己的自定义协议来通过网络进行流式传输,而不是QDataStream。
- 如何在Qt中创建多级QVariantMap
- QML/QT 无法将 C++ 中的 QList<QVariantMap> 转换为 JavaScript 中的对象数组
- QJson QVariantMap to QByteArray
- 与'operator[]'不匹配(操作数类型为 'QVariant' 和"常量字符 [2]") QVariant/QVariantMap
- 将 QByteArray 反序列化为多个 QVariantMap的
- 如何从另一个QVariantMap影响一个QVariantMap
- 无法将 QVariantMap 设置为 QML 属性
- 是否可以从qml访问持有QVariantMap的QScriptValue内部的任何内容
- Parsing a 2D QVariantMap
- 如何在Qt5中"merge"两个QVariantMap的内容?