如何序列化通过网络发送的对象

时间:2010-07-16 01:02:59

标签: c++ linux serialization sockets stream

我正在尝试序列化对象,仅使用STL通过套接字通过网络发送。我没有找到一种方法来保持对象的结构在其他主机中反序列化。我尝试转换为string,转换为char*,我花了很长时间在互联网上搜索教程,直到现在我一无所获。

有没有办法只使用STL?

有没有好的教程?

我差点尝试提升,但如果有STL的方法我想学习。

5 个答案:

答案 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)

通过网络套接字序列化C ++对象

这已经晚了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