繁体   English   中英

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

[英]How to serialize an object to send over network

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

有没有办法只用STL做到这一点?

有没有好的教程?

我差点尝试提升,但如果有STL怎么做我想学习。

你可以用任何东西序列化。 所有序列化的意思是您将对象转换为字节,以便您可以通过流(如std::ostream )发送它,并用另一个(如std::istream )读取它。 只需覆盖operator <<(std::ostream&, const T&)operator >>(std::istream&, T&) ,其中T是你的每个类型。 以及您的类型中包含的所有类型。

但是,你应该只使用一个已经存在的库(Boost非常好)。 像Boost这样的库为你做了很多事情,比如字节排序,处理常见对象(比如数组和标准库中的所有东西),提供了执行序列化和大量其他东西的一致方法。

我的第一个问题是:你想要序列化还是消息传递?

一开始看起来似乎很愚蠢,因为你要求序列化,但是我总是区分这两个术语。

  • 序列化是关于记录内存的快照并在以后恢复它。 每个对象都表示为一个单独的实体(尽管它们可能是由组成的)
  • 消息传递是指将信息从一个点发送到另一个点。 该消息通常具有自己的语法,可能无法反映您的业务模型的组织。

我经常看到人们使用Serialization,其中应该使用Messaging。 这并不意味着序列化是无用的,但它确实意味着你应该提前思考。 一旦您决定对其进行序列化,就很难改变BOM,特别是如果您决定重新定位某些信息(将其从一个对象移动到另一个对象)...因为您将如何解码“旧”序列化版本?

现在已经清理了......

......我会推荐谷歌的协议缓冲区。

你可以使用STL完全重写你自己,但你最终会完成已经完成的工作,除非你想从中学习,否则它是毫无意义的。

关于protobuf一个protobuf是它在某种程度上与语言无关:即你可以为C ++,Java或Python生成给定消息的编码器/解码器。 使用Python非常适合消息注入(测试)或消息解码(检查记录消息的输出)。 如果您使用STL,这不是一件容易的事情。

通过网络套接字序列化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++编译server.cppclient.cpp,并选择-std=c++11 然后,您可以打开两个终端并运行这两个程序,但是,在客户端之前启动服务器程序,以便它可以连接到某些程序。

希望这可以帮助。

我认为你应该在你的项目中使用谷歌协议缓冲区。在网络传输协议缓冲区有许多优于XML的序列化结构化数据的优势。 协议缓冲区:

更简单的是3到10倍小,快20到100倍,更少模糊生成数据访问类,更容易使用programmaticall

等等。 我想你需要阅读关于protobuf的https://developers.google.com/protocol-buffers/docs/overview

我知道了!

我使用strinstream来序列化对象,并使用stringstream的方法str()和字符串的c_str()将其作为消息发送。

看。

class Object {
public:
int a;
string b;

void methodSample1 ();
void methosSample2 ();

friend ostream& operator<< (ostream& out, Object& object) {
out << object.a << " " << object.b;   //The space (" ") is necessari for separete elements
return out;
}

friend istream& operator>> (istream& in, Object& object) {
in >> object.a;
in >> object.b;
return in;
}
};

/* Server side */
int main () {
Object o;
stringstream ss;
o.a = 1;
o.b = 2;
ss << o;    //serialize

write (socket, ss.str().c_str(), 20); //send - the buffer size must be adjusted, it's a sample
}

/* Client side */
int main () {
Object o2;
stringstream ss2;
char buffer[20];
string temp;

read (socket, buffer, 20);  //receive
temp.assign(buffer);
ss << temp;
ss >> o2;   //unserialize
}

我不确定是否有必要在序列化之前转换为字符串(ss << o),也许可以直接从char。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM