我正在尝试序列化对象,仅使用STL通过套接字通过网络发送。我没有找到一种方法来保持对象的结构在其他主机中反序列化。我尝试转换为string
,转换为char*
,我花了很长时间在互联网上搜索教程,直到现在我一无所获。
有没有办法只使用STL?
有没有好的教程?
我差点尝试提升,但如果有STL的方法我想学习。
答案 0 :(得分:7)
您可以使用任何内容进行序列化。所有序列化的意思是您将对象转换为字节,以便您可以通过流(如std::ostream
)发送它并使用另一个(如std::istream
)读取它。只需覆盖operator <<(std::ostream&, const T&)
和operator >>(std::istream&, T&)
,其中T
是您的每种类型。以及您的类型中包含的所有类型。
但是,你应该只使用一个已经存在的库(Boost非常好)。像Boost这样的库为你做了很多事情,比如字节排序,处理常见对象(比如数组和标准库中的所有东西),提供了执行序列化和大量其他东西的一致方法。
答案 1 :(得分:5)
我的第一个问题是:你想要序列化还是消息传递?
起初看起来很愚蠢,因为你要求序列化,但我总是区分这两个术语。
我经常看到人们使用Serialization,其中应该使用Messaging。这并不意味着序列化是无用的,但它确实意味着你应该提前思考。一旦您决定对其进行序列化,就很难改变BOM,特别是如果您决定重新定位某些信息(将其从一个对象移动到另一个对象)...因为您将如何解码“旧”序列化版本?
现在已经清理了......
......我会推荐Google的协议缓冲区。
你可以使用STL完美地重写你自己,但你最终会完成已经完成的工作,除非你想从中学习,否则它是毫无意义的。
关于protobuf
的一个好处是,它在某种程度上与语言无关:即,您可以为C ++,Java或Python生成给定消息的编码器/解码器。使用Python非常适合消息注入(测试)或消息解码(检查记录消息的输出)。如果您使用STL,那就不容易了。
答案 2 :(得分:1)
这已经晚了6年,但我最近遇到了这个问题,这是我在搜索如何通过C ++中的网络套接字序列化对象时遇到的一个主题。该解决方案仅使用2或3行代码。我发现有很多答案,但我发现最简单的方法是使用reinterpret_cast<obj*>(target)
将类或结构转换为字符数组并通过套接字提供它。这是一个例子。
要序列化的类:
/* myclass.h */
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass
{
public:
int A;
int B;
MyClass(){A=1;B=2;}
~MyClass(){}
};
#endif
服务器程序:
/* server.cpp */
#include "myclass.h"
int main (int argc, char** argv)
{
// Open socket connection.
// ...
// Loop continuously until terminated.
while(1)
{
// Read serialized data from socket.
char buf[sizeof(MyClass)];
read(newsockfd,buf, sizeof(MyClass));
MyClass *msg = reinterpret_cast<MyClass*>(buf);
std::cout << "A = " << std::to_string(msg->A) << std::endl;
std::cout << "B = " << std::to_string(msg->B) << std::endl;
}
// Close socket connection.
// ...
return 0;
}
客户计划:
/* client.cpp */
#include "myClass.h"
int main(int argc, char *argv[])
{
// Open socket connection.
// ...
while(1)
{
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
MyClass msg;
msg.A = 1;
msg.B = 2;
// Write serialized data to socket.
char* tmp = reinterpret_cast<char*>(&msg);
write(sockfd,tmp, sizeof(MyClass));
}
// Close socket connection.
// ...
return 0;
}
使用g++
{{1}编译 server.cpp 和 client.cpp 作为一个选项。然后,您可以打开两个终端并运行这两个程序,但是,在客户端之前启动服务器程序,以便它可以连接到某些程序。
希望这有帮助。
答案 3 :(得分:0)
答案 4 :(得分:0)
我认为你应该在你的项目中使用谷歌协议缓冲区。在网络传输协议缓冲区有许多优于XML的序列化结构化数据的优势。协议缓冲区:
更简单 比小3到10倍 比你快20到100倍 不那么暧昧 生成更易于使用的数据访问类programmaticall
等等。我想你需要阅读关于protobuf的https://developers.google.com/protocol-buffers/docs/overview