Vig*_*igo 11 c++ serialization winsock2 deserialization
假设我有一个结构,其成员值我想通过网络发送到使用winsock 2的另一个系统.我正在使用C++语言.我如何将其转换为char*记住结构必须在发送之前被序列化,以及如何将char*反序列化为另一端的struct?我发现boost序列化是对类似问题的建议,但任何人都可以通过一个小的代码片段来说明序列化和反序列化吗?
这个问题可能看起来很基本,但相关帖子的其他答案并没有多大帮助.
Ami*_*aka 16
以下示例显示了序列化struct
到char
数组并对其进行反序列化的最简单方法.
#include <iostream>
#include <cstring>
#define BUFSIZE 512
#define PACKETSIZE sizeof(MSG)
using namespace std;
typedef struct MSG
{
int type;
int priority;
int sender;
char message[BUFSIZE];
}MSG;
void serialize(MSG* msgPacket, char *data);
void deserialize(char *data, MSG* msgPacket);
void printMsg(MSG* msgPacket);
int main()
{
MSG* newMsg = new MSG;
newMsg->type = 1;
newMsg->priority = 9;
newMsg->sender = 2;
strcpy(newMsg->message, "hello from server\0");
printMsg(newMsg);
char data[PACKETSIZE];
serialize(newMsg, data);
MSG* temp = new MSG;
deserialize(data, temp);
printMsg(temp);
return 0;
}
void serialize(MSG* msgPacket, char *data)
{
int *q = (int*)data;
*q = msgPacket->type; q++;
*q = msgPacket->priority; q++;
*q = msgPacket->sender; q++;
char *p = (char*)q;
int i = 0;
while (i < BUFSIZE)
{
*p = msgPacket->message[i];
p++;
i++;
}
}
void deserialize(char *data, MSG* msgPacket)
{
int *q = (int*)data;
msgPacket->type = *q; q++;
msgPacket->priority = *q; q++;
msgPacket->sender = *q; q++;
char *p = (char*)q;
int i = 0;
while (i < BUFSIZE)
{
msgPacket->message[i] = *p;
p++;
i++;
}
}
void printMsg(MSG* msgPacket)
{
cout << msgPacket->type << endl;
cout << msgPacket->priority << endl;
cout << msgPacket->sender << endl;
cout << msgPacket->message << endl;
}
Run Code Online (Sandbox Code Playgroud)
你可以做
struct MyStruct {
int data;
char* someNullTerminatedName; // Assuming not larger than 1023 chars
std::ostream& serialize(std::ostream& os) const {
char null = '\0';
os.write((char*)&data, sizeof(data));
os.write(someNullTerminatedName, strlen(someNullTerminatedName));
os.write(&null, 1);
return os;
}
std::istream& deserialize(std::istream& is) {
char buffer[1024];
int i = 0;
is.read((char*)&data, sizeof(data));
do { buffer[i] = is.get(); ++i; } while(buffer[i] != '\0');
if (someNullTerminatedName != NULL) free(someNullTerminatedName);
someNullTerminatedName = (char*)malloc(i);
for (i = 0; buffer[i] != '\0'; ++i) {
someNullTerminatedName[i] = buffer[i];
}
return is;
}
};
Run Code Online (Sandbox Code Playgroud)
由您自己决定字节序和int
s 大小的差异以及诸如此类。
例:
MyStruct foo, bar;
std::stringstream stream;
foo.serialize(stream);
// ... Now stream.str().c_str() contains a char* buffer representation of foo.
// For example it might contain [ 1f 3a 4d 10 h e l l o w o r l d \0 ]
bar.deserialize(stream);
// ... Now bar is a copy, via a serial stream of data, of foo.
Run Code Online (Sandbox Code Playgroud)
如果您有一个通过C ++ iostream公开其接口的套接字库,那么您甚至不需要stringstream。
您还可以查看Google 的Protocol Buffers,它是一个独立于平台/语言的库,用于在主机之间发送数据。
然而,范式转向首先编写协议,然后将您的数据结构放入其中。这样做的好处是它迫使你的软件架构很好地适应简单的数据类型。
如果您的结构是POD
您可以使用memcpy
:
::memcpy(data, &your_struct, sizeof(YourStruct)));
反之亦然,在接待处:
::memcpy(&your_struct, data, sizeof(YourStruct)));
哪里data
有一个char*
. 不要忘记您必须分配它,确保它足够大并在最后删除它。
归档时间: |
|
查看次数: |
29293 次 |
最近记录: |