初探QT串行数据

在处理网络通信串行数据过程中(这里主要指socket通信)串行数据的发送和解析是一个重要的环节,对于socket通信常用的传输格式为字节流,所以通信时数据的串行化处理十分重要。这里首先说明下对串行数据解析的两种情况:1,串行数据为基本数据类型;2,串行数据为自定义数据类型如结构体。


QT中处理串行数据常用的类为QDataStream,通过它的接口函数可以轻松实现数据的串行化存储和读取,这个类通过绑定IO接口(socketIO设备、文件等)实现对目标文件内容的串行操作。存储原始二进制文件的常用类为QByteArray,这个类不是从IODevice继承过来的,但可以通过QDataStream实现数据的存储与操作。下面说明下使用过程和存在的坑!


1:通过QDataStreamQByteArray写入字符串


通过QDataStreamQByteArray中写入QString,查看内存中数据存储情况。发现存储的数据与预想的不一样,QString的存储数据格式在头部4个字节表示数据的总长度(字节),最后没有“0”来代表字符串的结束,QString类型下的“test”字符串数据总长度达到12字节!代码如下:

结果:

前四个字节0x00 0x00 0x00 0x08 表示后续字符串数据的长度为8,后面8个字节为具体的字符串内容0x00 0x74 0x00 0x65 0x00 0x73 0x00 0x74至于为什么为8个字节存储4个字符与编码有关,QT中的QString采用16字节来编码字符。

再验证一次:


结果:


恩,不出所料和预想的一样,下一个QString("again")存储过程中又增加了4字节的头!这是QString进行跨平台通信时需要注意的,否则解析数据时容易出错。那const char在QT中的存储结构有什么变化吗,我试了一下:


结果:


这里可以发现对于const char,不但存储结构中前4个字节保存了后续数据的字节长度,而且在字符数据的末端添加了一个“0”作为字符串的终止符号,但是呢,这里因为是char类型,所以数据存储为8位,数据的总长度反而降低了。


2、基本类型数据在QByteArray中的存储


了解了字符串的在QT中的存储格式问题下面看看其他基本类型的存储过程,这里以intdouble为例,首先看看int的存储,依旧先上图:


结果:


可以看到存储的数据为4个字节,没有额外的附加数据,但是解析的结果出现问题!!!仔细观察可以发现原来是因为数据的存储是大端格式(高位字节在低位内存位置)而我的电脑是小端,所以需要大小端转换,本来不用这么麻烦,为了理解原理,这里自己就用最笨的办法试验了一下:

结果:

恩,这么笨而传统的办法当然是没有任何问题了。对于double也存在这样的问题,可以类似的方法处理:



结果嘛:


直接通过QDataStream设置数据的大小端,这个样就可以在复制内存的时候不用考虑大小端的转换问题了。网络通信过程中默认为大端传输,值得注意的是,QByteArray通过QFile完成与QDataStream的交互,所以每次写入时指针都在末尾,从头读出需要seek(0)到数据内容的头部。





可以看到结果没有任何问题。初次接触QT的串行数据处理,小小的总结一下。


猜你喜欢

转载自blog.csdn.net/RaoJohn/article/details/78466169