Как сериализовать объект для отправки по сети

Я пытаюсь сериализовать объекты для отправки по сети через сокет, используя только STL. Я не нахожу способ сохранить структуру объектов для десериализации на другом хосте. Я попытался преобразовать в string, to char* и я потратил много времени на поиск учебников в интернете, и до сих пор я ничего не нашел.

есть ли способ сделать это только с STL?

есть ли хорошие учебники?

я почти пытаюсь увеличить, но если есть как чтобы сделать это с STL, я хотел бы научиться.

5 ответов


вы можете сериализовать с чем угодно. Вся сериализация означает, что вы преобразуете объект в байты, чтобы вы могли отправить его по потоку (например,std::ostream) и прочитать его с другим (например,std::istream). Просто переопределите operator <<(std::ostream&, const T&) и operator >>(std::istream&, T&) здесь T каждый из ваших типов. И все типы, содержащиеся в ваших видах.

однако вы, вероятно, должны просто использовать уже существующую библиотеку (Boost довольно хороший). Есть тонны вещей, которые библиотека, как Boost делает для вас, как упорядочение байтов, заботясь об общих объектах (таких как массивы и все вещи из стандартной библиотеки), обеспечивая последовательные средства выполнения сериализации и тонны других вещей.


мой первый вопрос: вы хотите сериализацию или обмен сообщениями ?

  • сериализация - это снимок вашей памяти и ее восстановление позже. Каждый объект представлен как отдельная сущность (хотя они могут быть составлены)
  • сообщениями об отправке информации из одной точки в другую. Сообщение как правило, имеет свою собственную грамматику и может не отражать организацию вашей бизнес-модели.

слишком часто я видел людей, использующих сериализацию, где должны были использоваться сообщения. Это не означает, что сериализация бесполезна, но это означает, что вы должны думать заранее. Довольно сложно изменить спецификацию после того, как вы решили сериализовать ее, особенно если вы решили переместить некоторую часть информации (переместить ее с одного объекта на другой)... потому как тогда вы собираетесь декодировать" старую " сериализованную версию ?

теперь, когда это прояснилось...

... Я порекомендую буфер протокола Google.

вы можете отлично переписать свой собственный, используя STL, но вы в конечном итоге будете делать работу, которая уже была сделана, и если вы не хотите учиться на ней, это совершенно бессмысленно.

одна большая вещь о 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;
}

компилировать как сервер.cpp и клиент.cpp используя g++ С -std=c++11 как вариант. Затем вы можете открыть два терминала и запустить обе программы, однако запустите серверную программу перед клиентом, чтобы ему было к чему подключиться.

надеюсь, что это помогает.


Я понял!

я использовал 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


Я думаю, вы должны использовать буферы протокола google в своем проекте.В протоколе сетевого транспорта буферы имеют много преимуществ перед XML для сериализации структурированных данных. Буферы протокола:

проще в 3-10 раз меньше в 20-100 раз быстрее менее неоднозначны создайте классы доступа к данным, которые проще использовать programmaticall

и так далее. Я думаю, вам нужно прочитать https://developers.google.com/protocol-buffers/docs/overview о protobuf