写了一个小的Qt网络程序,很简单,发送的网络消息除了字符串还有一个结构体。很简单的想到用memcpy()函数来将数据序列化为BYTE数组从而实现网络传输。

序列化是Java中一个概念,C中并没有,C++中后来引入了序列化和反序列化的概念。序列化是指将非系统类型的类的对象通过序列化操作转换成基本数据格式,从而达到便于网络传输或者文件读写的目的。反序列化是序列化的逆操作。

注:C/C++中BYTE与Char在内存中数据一样,形式相同,在Windef.h中有一行:

  typedef unsigned char BYTE;

故而,在内存中char和BYTE是一样的,序列化的目标为BYTE和char是等效的。

而QUdpSocket需要的是char型的网络传输格式,序列化的结果就是BYTE或者char型。

而序列化为char型,就不得不提C/C++中的内存对准问题,个人的经验是尽量多用char、BYTE等定长类型,少用int,double等变长类型,来进行序列化,因为在不同系统中,变长类型会因为系统的不同而定义为不同长度的内存位,进而系统会特定性的进行内存对齐,导致序列化后的反序列化出现乱码。

实在需要使用类似的结构或者类型,则尽量将其岔开,并且通过不同长度类型隔开来保证内存始终对齐至理想位置。并且,相对的,尽量将“较大”的类型变量靠前放置。

-------------------------------------------------------------------------------------------------------

现在描述遇到的问题:

  需求:通过Qt界面得到操作信息,并保存到一个结构体中,初始化一个UDPSocket对象,将结构体序列化为char型后,通过网络发送。

  实现:Qt界面通过QImage类的对象,得到图像信息并获取操作数据。自定义结构体如下:

 typedef struct tagDrawInfo
{
TOOLS m_Tool; /// 绘图工具;TOOLS为自定义enum联合体。
int width; /// 画笔宽度;
QColor lineColor; /// 线条颜色;
QColor fillColor; /// 填充颜色;
Qt::BrushStyle
brushStyle; /// 画刷风格;
QPoint startPoint; /// 开始点;
QPoint endPoint;  /// 结束点;
}DRAWINFO;

  通过memcpy()函数来实现内存拷贝,达到序列化的目的。

  问题:接收端得到的DRAWINFO对象,值为意料之外值,进而程序不能通过当前对象完成进一步操作。

  解决:1)自己定义序列化函数,将特定对象放置于指定位置,保证反序列化时数据位置和预期一样。分别对结构体的每部分序列化和反序列化,利用各类型的构造函数初始化对象,完成反序列化。

     2)对DRAWINFO定义顺序进行调整,对变长类型对象进行分离,确保系统内存的自动对齐不会对数据位置产生影响。更改过后的结构体定义如下:

 typedef struct tagDrawInfo
{
  Qt::BrushStyle
brushStyle; /// 画刷风格;
QPoint endPoint;  /// 结束点;
QColor fillColor; /// 填充颜色;
QColor lineColor; /// 线条颜色;
TOOLS m_Tool; /// 绘图工具;TOOLS为自定义enum联合体。
QPoint startPoint; /// 开始点;
int width; /// 画笔宽度;
}DRAWINFO;

  结果:对定义顺序进行调整后,接收端的DRAWINFO对象反序列化功能正常。

  分析:C++编译器,会对int型、bool型等边长类型进行内存对齐,提高内存利用效率,进而提高CPU一个工作周期内可处理指令条数,提高程序运行效率,但是在自动完成一些功能时会产生意外的问题,需要适当调整。

  而关于内存对准的问题,今天欠下一笔,日后有时间进行详解~

Qt中QUdpSocket序列化问题的更多相关文章

  1. QT中的线程与事件循环理解(1)

    1.需要使用多线程管理的例子 一个进程可以有一个或更多线程同时运行.线程可以看做是“轻量级进程”,进程完全由操作系统管理,线程即可以由操作系统管理,也可以由应用程序管理.Qt 使用QThread 来管 ...

  2. Qt 框架的图形性能高(OpenGL上的系统效率高),网络性能低,开发效率高,Quick是可以走硬件加速——Qt中分为好几套图形系统,差不多代表了2D描画的发展史。最经典的软描画系统

    -----图形性能部分-----Qt的widgets部分,运行时的图像渲染性能是一般的,因为大部分的界面内容都是Qt自绘,没有走硬件加速,也就是说很多图形内容都是CPU算出来的.但是widgets底层 ...

  3. 关于QT中的音频通信问题

    今天给大家讲说一个新的东西,使用QT实现音频通信的功能,挺起来是不是很高大上啊,哈哈,实际上我们只是使用一些接口做一些简单的工作而已,并不是让你写一个传输协议和采集音频信息,好了,那我们就来说一说关于 ...

  4. 4.关于QT中的QFile文件操作,QBuffer,Label上添加QPixmap,QByteArray和QString之间的区别,QTextStream和QDataStream的区别,QT内存映射(

     新建项目13IO 13IO.pro HEADERS += \ MyWidget.h SOURCES += \ MyWidget.cpp QT += gui widgets network CON ...

  5. QT中使用MinGW 编译的protobuf库--包含库的生成和使用

    QT中使用MinGW 编译的protobuf库--包含库的生成和使用 0前言 1准备工作 2生成protobuf库文件 3在QT中测试protobuf的使用 4结语 0前言 最近要在QT中使用prot ...

  6. Qt中使用Json

    Qt中使用Json需要一下几个类: QJsonValue            代表了json格式中的一个值 QJsonObject          代表了json格式的一个对象 QJsonArra ...

  7. 4.关于QT中的QFile文件操作,QBuffer,Label上加入QPixmap,QByteArray和QString之间的差别,QTextStream和QDataStream的差别,QT内存映射(

     新建项目13IO 13IO.pro HEADERS += \ MyWidget.h SOURCES += \ MyWidget.cpp QT += gui widgets network CON ...

  8. Qt 中使用Singleton模式需小心

    在qt中,使用Singleton模式时一定要小心.因为Singleton模式中使用的是静态对象,静态对象是直到程序结束才被释放的,然而,一旦把该静态对象纳入了Qt的父子对象体系,就会导致不明确的行为. ...

  9. qt中ui的 使用介绍

    1.什么是ui?ui通常是用Qt 设计师设计出来的界面文件的后缀.通常情况下ui是一个指向这个界面类的指针.ui-> 一般就是用来访问这个界面类里面的控件.例如你的ui文件里有一个叫okButt ...

随机推荐

  1. iOS 关于UITableView的dequeueReusableCellWithIdentifier

    今天看代码的时候,突然想到了以前的一个问题. 刚学ios那会儿,常会写出以下代码 - (UITableViewCell *)tableView:(UITableView *)tableView cel ...

  2. eclipse 向HDFS中创建文件夹报错 permission denied

    环境:win7  eclipse    hadoop 1.1.2 当执行创建文件的的时候, 即: String Path = "hdfs://host2:9000"; FileSy ...

  3. mysql 源码包 有的版本 可能没有 CMakeCache.txt

    如果没有CMakeCache.txt 文件编译的时候会报错!!找不到CMakeCache.txt

  4. jquery easy ui 1.3.4 内容组件(2)

    2.1.panel(面板) panel面板是easyui里面非常基础的一个内容组件,在我们后期学的tabs (选项卡).accordion(手风琴)这两种内容组件都依赖于panel组件.构建一个pan ...

  5. 【ACM - 搜索模板】

    [广搜模板] #include <iostream> #include <stdio.h> #include <string.h> #include <que ...

  6. ytu 1980:小鼠迷宫问题(DFS 深度优先搜索)

     小鼠迷宫问题 Time Limit: 2 Sec  Memory Limit: 64 MB Submit: 1  Solved: 1 [Submit][Status][Web Board] Desc ...

  7. Android种 adb是什么(转)

    提到adb.exe,一直关注我们Android系列教程的朋友们应该不会感到陌生,因为无论取得 Root权限或者刷机的时候我们都通过adb直接操作管理Android手机,但是可能大多数对于adb仅仅局限 ...

  8. ML 03、机器学习的三要素

    机器学习算法原理.实现与实践——机器学习的三要素 1 模型 在监督学习中,模型就是所要学习的条件概率分布或决策函数.模型的假设空间包含所有可能的条件概率分布或决策函数.例如,假设决策函数是输入变量的线 ...

  9. loj 1407(2-sat + 枚举 + 输出一组可行解 )

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27115 思路:有一个trick要注意:当情况为 2 x y 时,可 ...

  10. cocos2dx游戏开发——微信打飞机学习笔记(十)——碰撞检测的搭建

    一.七说八说        大家都发现了= =,做了那么多,发现就是摆设,完全没有打飞机的感觉,没有实现碰撞的监测.比如说呢,子弹和敌机,玩家与敌机就是需要有碰撞检测的说,然后在这篇我想会很长很长的教 ...