簡體   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