更多网络问题。我偶然发现了这个问题:Serialization/Deserialization of a struct to a char* in C并且很多答案都有意义,但我一遍又一遍地看到的是所有数据包似乎都带有的'char data'字段。
现在我知道它的用途 - 您在此处存储要发送的数据。但是如何实际将数据写入其中呢?有没有办法在这个数据字段中存储整个对象?或者我以某种方式序列化对象,将其存储在数据中,然后在我发送所有内容之前序列化数据包..?
答案 0 :(得分:1)
计算机内存中存在每个变量。内存按字节组织。
当您编写C ++代码时,您可以直接读取这些字节。对于struct,其所有成员的内存都在一个连续的块中(尽管每个成员之间可能存在间隙)。
所以,如果我宣布:
struct foo {
char x;
char y;
short z;
int q;
};
然后当我创建struct foo
时,我在内存中得到以下布局(大多数系统上总共8个字节):
xyzzqqqq
第一个字节是x
,第二个y
,第三个和第四个一起是z
,后四个是q
。
因此,对象已经“序列化” - 你有一堆代表它的字节。这就是您需要通过网络发送的所有内容:代表数据结构的信息。
您编写自己的序列化程序的原因是您可能希望更改读取或写入对象的方式(例如,如果我向{{1}添加了字段,该怎么办?因为你需要在内存布局不同的机器之间进行通信(struct foo
的哪个字节代表数字的“最重要”部分?),或者因为你只想序列化部分结构(如果我们在成员之间有一些空的空间怎么办?)。
但是,从根本上说,你发送“char数据”的原因是因为你的计算机中的所有内容都可以用这种方式表示。我不会进入图灵关于符号编码的证明,但这是一种数学证据,任何知识都可以被编码为一系列的零和零。
更具体地说,将数据放入数据包的“char数据”字段的方式是z
数据当前进入缓冲区的位置。所以如果我有一个memcpy
,我可以在其中写一个char* target
:
struct foo x
或者我可以通过编写每个字段来更仔细地做到:
memcpy(target, &x, sizeof(struct foo));
memcpy(target, &x.x, 1);
memcpy(target+1, &x.y, 1);
memcpy(target+2, &x.z, sizeof(short));
memcpy(target+4, &x.q, sizeof(int));
是地址运营商,如果您还不知道的话。所以我从每个成员的地址写入&
内的某个偏移量,并写入一些等于成员变量表示长度的字节。
您对上一个问题的接受答案指出,这是过于简单化的:当您通过网络发送多字节整数时,您必须担心 endianness (字节顺序)。所以你实际做的是:
target
这将处理反转字节,以便从主机字节顺序转换为网络字节顺序。显然,一个字节长的值是免疫的。