1.结构体字节流化可能会出现的问题
网络编程里很多时候需要发送结构体,比如下面定义一个最简单的拥有多个元素的结构体
typedef struct msg{
int len;
char name[24];
} msg_t;
在保持客户端和服务端程序的结构体定义一致的前提下,这种可能会有内存对齐的问题,比如现在的顺序是len和name分别先后,进行操作
字节流化,通过网络程序发送,再反序列化出来
这样做可能没问题,但是如果把两个结构体变量的先后顺序反过来,再进行上述操作,那可能会导致反序列化出来的结果究极奇怪。
用#pragma pack(1)让结构体的元素内存对齐是按照1个字节的方式,那么上面的结构体就该这样写
#pragma packed(1)
typedef struct msg{
enum MESSAGE_TYPE type;
int len;
char name[24];
} msg_t;
用这个办法可以不去考虑字节对齐的问题,而随意修改结构体变量定义的先后顺序。当然这样做会不可避免的有性能损耗
2.收发的数据不一致,输出的缺斤少俩
引起这个问题可能有以下原因
1.是因为上面字节流化时候没做好,导致这样
2.查看发送的buffer是否因为长度不够被截断了
第二点可能是在调用recv或send,或者read/write等需要指定长度时候传参错误,在保证结构体里不含指针的前提下,如上面的结构,可以直接传递sizeof。
3. 输出的是个奇怪玩意儿,而且每次都变
这种情况大概率是发送了一个指针,可能会输出下面的类似内容
1.有几种可能会出现问题的地方,比如上面的结构体变成如下所述。
#pragma pack(1)
typedef struct msg{
char* name;
int len;
} msg_t;
在项目里可能会有typedef出来一堆别名,比如windows里有PWORD是一个void*。
2.结构体字节化成buffer或者逆序的过程
强制转换的过程可能少了&或者少了*
msg_t send_msg;
char* buffer = (char*)&send_msg;
msg_t* recv_msg = (msg_t*)buffer;