序列化问题,同时发送结构通过套接字 [英] Serialization issues while sending struct over socket

查看:127
本文介绍了序列化问题,同时发送结构通过套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发基于UDP我想不同的消息从服务​​器发送到客户端的客户端/服务器。有每个消息定义不同的C结构。

我想了解什么是错的,我序列化数据的方式。

 结构任务
{
    INT MTYPE;
    INT Af - Ag型;
    诠释CCNT;
    INT * CID;
    CHAR数据[128];
};

序列化/反序列化功能

 无符号字符* serialize_int(无符号字符*缓冲区,int值)
{
    缓冲器[0] =值GT;> 24;
    缓冲液[1] =值GT;> 16;
    缓冲液[2] =值GT;> 8;
    缓冲[3] =价值;
    返回缓冲区+ 4;
}无符号字符* serialize_char(无符号字符*缓冲区,char值)
{
    缓冲区[0] =价值;
    返回缓冲区+ 1;
}INT deserialize_int(无符号字符*缓冲区)
{
    int值= 0;    值| =缓冲[0]<< 24;
    值| =缓冲[1];< 16;
    值| =缓冲[2]<< 8;
    值| =缓冲区[3];
    返回值;}焦炭deserialize_char(无符号字符*缓冲区)
{
    返回缓冲器[0];
}

发送方code序列化结构

 无符号字符* serializeTask(无符号字符*味精,常量任务* T)
{
    味精= serialize_int(味精,T-> M型);
    味精= serialize_int(味精,T-> tkType);
    味精= serialize_int(味精,T-> CCNT);
    的for(int i = 0; I< T-> CCNT;我++)
            味精= serialize_int(味精,T-> CID [I * 4]);的for(int i = 0; I< strlen的(数据);我++)
    味精= serialize_char(味精,T->数据[I]);    返回味精;
}

接收方code反序列化数据

 的printf(消息类型:%d个\\ N,deserialize_int(消息));
的printf(任务类型:%d个\\ N,deserialize_int(消息+ 4));
的printf(任务数数:%d \\ n,deserialize_int(消息+ 8));产量
消息类型:50364598 //期望值为3
任务类型:-2013036362 //期望值为1
任务计数:1745191094 //期望值为3

问1:结果
为什么不一样的预期反序列化的价值?

问题2:结果
如何序列化/反序列化的方法,从不同的memcpy?

 任务吨;
的memcpy(& T公司,味精,sizeof的(T)); // msg是无符号字符*持有的结构数据

修改

code它调用 serializeTask

 无效addToDatabase(无符号字符*消息,诠释msgSize,任务*任务)
{
    消息=新的无符号的char [2 * msgSize + 1];
    无符号字符*味精=消息; //为preserve启动消息的地址
    消息= serializeTask(邮件,任务); //现在信息点,结束该阵列的//插入序列数据DB
//味精插入到数据库
}

存储在数据库序列化数据

 消息:
00
03 70 88 B6 70 03 68 B6 70 05 68 B6 70 05 00 B6
00 00 00 00 00 00 00 A8 05 70 B6交流05 70 B6 B4
05 70 B6 C9 05 70 B6 DE 05 70 B6 E6 05 70 B6 EE
05 70 B6 FB 05 70 B6 64 65 66 00 63 68 6F 72 6F
74 73 00 70 65 64 6E 69 67 6E 61 5F 73 73 69 67
6E 5F 74 61 73 73 6B 70 00 65 64 6E 69 67 6E 5F
61 73 73 69 67 6E 5F 74 61 73 73 6B 00 6D 65 73
73 61 67 65 00 65 6D 73 73 61 67 65 00 00 3F FF
FF 00 00 FC 90 00 00 00 00 00 00 00 C9 2D B7 00
00 00 00 10 06 70 B6 00 00 00 00 00 00 00 00 30
06 70 34 B6 70 06 B6 3C 06 70 B6


解决方案

OP在 serializeTask 2个问题()

 的for(int i = 0; I< T-> CCNT;我++)
  味精= serialize_int(味精,T-> CID [I * 4]); [我* 4]
...
的for(int i = 0; I< strlen的(数据);我++)
  味精= serialize_char(味精,T->数据[I]); strlen的(数据)

应该是(假设 I< strlen的(数据)应该是 I<的strlen(叔>数据)

 的for(int i = 0; I< T-> CCNT;我++)
  味精= serialize_int(味精,T-> CID [I]); // [一世]
...
的for(int i = 0; I<的strlen(叔>数据);我++)// strlen的(数据)+ 1
  味精= serialize_char(味精,T->数据[I]);

第一个for循环连载每4个 CID [] 。 OP肯定要连续序列 CID [] 。结果
数据只有长度串连载。 OP肯定想序列化所有的的一个NUL终止字节。


在公布缓冲区中的数据更可能下面,这确实的的匹配序列化code。这意味着上级code填充任务* T 是错误的。我相信, M型 tkType 在字段中看到的值不是指针或浮动,又任务* T 可能是不妥的串行化之前。

  0xb6700300或-3.576453e-06
0xb6700388或-3.576484e-06
0xb6700568或-3.576593e-06
0xb6700568或-3.576593e-06
0x000000处或0.000000e + 00
0x000000处或0.000000e + 00
0xb67005a8或-3.576608e-06
0xb67005ac或-3.576609e-06
0xb67005b4或-3.576611e-06
0xb67005c9或-3.576615e-06
0xb67005de或-3.576620e-06
0xb67005e6或-3.576622e-06
0xb67005ee或-3.576624e-06
0xb67005fb或-3.576627e-06
高清\\ 0cohorts \\ 0pending_assign_tasks \\ ​​0pending_assign_tasks \\ ​​0message \\ 0message \\ 0?\\ 0
...

I am developing a Client/Server based on UDP I want to send different messages to the client from the server. There are different C structures defined for each message.

I would like to understand what is wrong in the way I am serializing the data.

struct Task
{
    int mType;
    int tType;
    int cCnt;
    int* cId;
    char data[128];
};

Serialization/Deserialization functions

unsigned char * serialize_int(unsigned char *buffer, int value)
{
    buffer[0] = value >> 24;
    buffer[1] = value >> 16;
    buffer[2] = value >> 8;
    buffer[3] = value;
    return buffer + 4;
}

unsigned char * serialize_char(unsigned char *buffer, char value)
{
    buffer[0] = value;
    return buffer + 1;
}

int deserialize_int(unsigned char *buffer)
{
    int value = 0;

    value |= buffer[0] << 24;
    value |= buffer[1] << 16;
    value |= buffer[2] << 8;
    value |= buffer[3];
    return value;

}

char deserialize_char(unsigned char *buffer)
{
    return buffer[0];
}

Sender side code to serialize the structure

unsigned char* serializeTask(unsigned char* msg, const Task* t)
{
    msg = serialize_int(msg,t->mType);
    msg = serialize_int(msg,t->tkType);
    msg = serialize_int(msg,t->cCnt);
    for(int i=0; i<t->cCnt; i++)
            msg = serialize_int(msg,t->cId[i*4]);

for(int i=0; i<strlen(data); i++)
    msg = serialize_char(msg,t->data[i]);

    return msg;
}

Receiver side code to de-serialize data

printf("Msg type:%d\n", deserialize_int(message) );
printf("Task Type:%d\n", deserialize_int(message+4) );
printf("Task Count:%d\n", deserialize_int(message+8));

Output 
Msg type:50364598         //Expected value is 3
Task Type:-2013036362     //Expected value is 1
Task Count:1745191094     //Expected value is 3  

Question 1:
Why is the de-serialized value not same as expected?

Question 2:
How is serialization/de-serialization method different from memcpy?

Task t;
memcpy(&t, msg, sizeof(t));  //msg is unsigned char* holding the struct data  

EDIT

Code which invokes serializeTask

void addToDatabase(unsigned char* message, int msgSize, Task* task)
{
    message = new unsigned char[2*msgSize+1];
    unsigned char* msg = message;  //To preserve start address of message
    message = serializeTask(message, task); //Now message points to end of the array

//Insert serialized data to DB
//msg is inserted to DB 
}

Serialized data stored in DB

Message:
00 
03 70 B6 88 03 70 B6 68 05 70 B6 68 05 70 B6 00 
00 00 00 00 00 00 00 A8 05 70 B6 AC 05 70 B6 B4 
05 70 B6 C9 05 70 B6 DE 05 70 B6 E6 05 70 B6 EE 
05 70 B6 FB 05 70 B6 64 65 66 00 63 6F 68 6F 72 
74 73 00 70 65 6E 64 69 6E 67 5F 61 73 73 69 67 
6E 5F 74 61 73 6B 73 00 70 65 6E 64 69 6E 67 5F 
61 73 73 69 67 6E 5F 74 61 73 6B 73 00 6D 65 73 
73 61 67 65 00 6D 65 73 73 61 67 65 00 3F 00 FF 
FF 00 00 FC 90 00 00 00 00 00 00 00 C9 2D B7 00 
00 00 00 10 06 70 B6 00 00 00 00 00 00 00 00 30 
06 70 B6 34 06 70 B6 3C 06 70 B6

解决方案

OP has 2 problems in serializeTask()

for(int i=0; i<t->cCnt; i++)
  msg = serialize_int(msg,t->cId[i*4]); [i*4]
...
for(int i=0; i<strlen(data); i++)
  msg = serialize_char(msg,t->data[i]); strlen(data)

Should be (assuming i<strlen(data) should have been i<strlen(t->data)

for(int i=0; i<t->cCnt; i++)
  msg = serialize_int(msg,t->cId[i]);  // [i]
...
for(int i=0; i<strlen(t->data); i++)   // strlen(data) + 1
  msg = serialize_char(msg,t->data[i]);

The first for loop serialize every 4th cId[]. OP certainly wanted to serialize consecutive cId[].
Only the length of the data string was serialized. OP certainly wanted to serialize all that and a NUL terminating byte.


The data in the posted buffer is more likely the below, which does not match the serialization code. This implies the higher level code populating Task* t is wrong. I am confident that the values seen in fields mType and tkType are either pointers or float, again Task* t is likely amiss before the serialization.

0xb6700300 or -3.576453e-06
0xb6700388 or -3.576484e-06
0xb6700568 or -3.576593e-06
0xb6700568 or -3.576593e-06
0x000000 or 0.000000e+00
0x000000 or 0.000000e+00
0xb67005a8 or -3.576608e-06
0xb67005ac or -3.576609e-06
0xb67005b4 or -3.576611e-06
0xb67005c9 or -3.576615e-06
0xb67005de or -3.576620e-06
0xb67005e6 or -3.576622e-06
0xb67005ee or -3.576624e-06
0xb67005fb or -3.576627e-06
def\0cohorts\0pending_assign_tasks\0pending_assign_tasks\0message\0message\0?\0
...

这篇关于序列化问题,同时发送结构通过套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆