写了一个小的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. Python之property装饰器

    参考: http://www.cnblogs.com/lovemo1314/archive/2011/05/03/2035600.html http://joy2everyone.iteye.com/ ...

  2. java文件上传路径缺少\的解决办法

    今天做一个文件上传,取路径,然后读取文件的时候,发现存储到MySQL的路径是这样的:

  3. Java关于队列的自我实现

    1.循环队列的封装 package com.pinjia.shop.common.collection; /** * Created by wangwei on 2016/12/29. * 循环队列的 ...

  4. 深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结

    转自 http://www.jb51.net/article/37527.htm,感谢作者 #include "stdafx.h"      #include <iostre ...

  5. decltype

    在C++中,decltype作为操作符,用于查询表达式的数据类型.decltype在C++11标准制定时引入,主要是为泛型编程而设计,以解决泛型编程中,由于有些类型由模板参数决定,而难以(甚至不可能) ...

  6. 经典创意slogan大全

    一句好的广告语,能强烈的激发人的感情,产生心理认同感.对于广告人来说,无论走到哪里,最敏感的就是广告语.一句广告语,可能只有短短几个字或一两句话,却是一个品牌的精华所在.能不能第一时间吸引受众眼球,抓 ...

  7. hdu 1242:Rescue(BFS广搜 + 优先队列)

    Rescue Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

  8. hdu 2108:Shape of HDU(计算几何,判断多边形是否是凸多边形,水题)

    Shape of HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  9. Query通过Ajax向PHP服务端发送请求并返回JSON数据

    Query通过Ajax向PHP服务端发送请求并返回JSON数据 服务端PHP读取MYSQL数据,并转换成JSON数据,传递给前端Javascript,并操作JSON数据.本文将通过实例演示了jQuer ...

  10. Web service project中导入的库JAXB(JDK1.7新产品,组成部分)

    JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例文档反向 ...