Frage

Ich habe eine Datenstruktur, die wie folgt aussieht:

typedef struct
{
  unsigned short m_short1;
  unsigned short m_short2;
  unsigned char m_character;
} MyDataType;

Ich will boost verwenden :: Serialisierung diese Datenstruktur serialisiert werden, dann boost :: asio es über TCP / IP zu übertragen, haben dann eine andere Anwendung die Daten empfangen und deserialisieren es die gleichen Boost-Bibliotheken.

ich auf folgenden Schub versuchen :: Serialisierung Tutorial ( wie einige andere sO Fragen haben vorgeschlagen, ), aber das Beispiel ist speziell für das Schreiben / in eine Datei zu lesen, nicht an eine Steckdose mit boost :: asio.

Ich bin mir ziemlich sicher, dass ich die richtigen Werkzeuge für den Job habe - ich brauche nur helfen, sie arbeiten zusammen zu machen. Das Schreiben an eine Steckdose kann das nicht anders sein, in eine Datei zu schreiben, nicht wahr?

Alle Vorschläge sind sehr geschätzt. Dank!

War es hilfreich?

Lösung

Für eine solche einfache Struktur, boost :: Serialisierung ist übertrieben und großen Aufwand.

Sie einfacher:

vector<uint16_t> net(3,0);

net[0]=htons(data.m_short1);
net[1]=htons(data.m_short2);
net[2]=htons(data.character);

asio::async_write(socket,buffer((char*)&net.front(),6),callback);

vector<uint16_t> net(3,0);
asio::async_read(socket,buffer((char*)&net.front(),6),callback);

callback:
data.m_short1=ntohs(net[0]);
data.m_short2=ntohs(net[1]);
data.character=ntohs(net[2]);

Und Sparen Sie sich riesig Overhead, der boost :: Serialisierung hat

Und wenn Sie privates Protokoll, bei dem Computer mit dem gleichen Reihenfolge der Bytes Arbeit (groß / klein) dass nur Struktur senden wie -. POD

Andere Tipps

Es gibt eine gute Serialisierung Beispiel in der Asio Dokumentation: server.cpp , stock.hpp , connection.hpp .

Hier ist ein Ausschnitt:

std::ostringstream archive_stream;
boost::archive::text_oarchive archive(archive_stream);
archive << your_struct;
outbound_data_ = archive_stream.str();
boost::asio::async_write(socket_, 
    boost::asio::buffer(outbound_data_), handler);

Ich dachte, ich dies mit niemandem teilen würde, die ein C ++ struct mit Boost-Serialisierung versucht. Für das obige Beispiel gegeben, um die struct serializable Sie eine serialize Funktion hinzufügen würde:

typedef struct
{
  unsigned short m_short1;
  unsigned short m_short2;
  unsigned char m_character;

  template <typename Archive>
  void serialize(Archive& ar, const unsigned int version)
  {
    ar & m_short1;
    ar & m_short2;
    ar & m_character;
  }
} MyDataType;

EDIT: Ich nehme zurück, um meine Antwort unten, was ich vorgeschlagen hat, die Zeit und Raum Vorteile gegenüber der Lösung, aber string die asio :: Stream API einige wichtige Funktionen fehlen, die in einem langen Lauf benötigt werden (zB zeitlich Unterbrechung ).


Meine ursprüngliche Antwort:

Verwenden Ströme von boost :: asio, hat es Zeit und Raum Vorteile gegenüber es in std :: stringstreams zu schreiben und sie dann in einem Rutsch zu senden. Hier ist, wie:

Client-Code:

boost::asio::ip::tcp::iostream stream("localhost", "3000");

if (!stream)
  throw std::runtime_error("can't connect");

Server-Code:

boost::asio::io_service ios;
boost::asio::ip::tcp::endpoint endpoint
  = boost::asio::ip::tcp::endpoint(ip::tcp::v4(), 3000);
boost::asio::ip::tcp::acceptor acceptor(ios, endpoint);
boost::asio::ip::tcp::iostream stream;

// Your program stops here until client connects.
acceptor.accept(*stream.rdbuf()); 

Und dann, nachdem Sie mit entweder Client oder Server-Stream verbunden sind gerade tun:

MyDataType obj;

// Send the object.
boost::archive::text_oarchive archive(stream);
archive << obj;

// Or receive it.
boost::archive::text_iarchive archive(stream);
archive >> obj;

Sie müssen natürlich die ‚serialize‘ -Funktion in Ihre myDataType hinzufügen, wie Tymek in seiner Antwort schrieb.

tun Sie die Serialisierung boost :: Archiv, das Konstruktorparameter bekommen - Zielstrom, in dem Sie Daten speichern wird. Sie könnten boost.iostreams Bibliothek verwenden für Ihren eigenen Strom definieren, welche Daten über das Netzwerk senden, anstatt Datei oder nur Asio Buchse Ströme ( http://www.boost.org/doc/libs/1_36_0/doc/html/boost_asio/reference/ip__tcp/iostream.html ). Es ist eine gute Art und Weise, wir etwas ähnliches auf das tun, aber wir haben einige Ströme (zip / Verschlüsselungs- / Senden) und verwenden boost iostreams Bibliothek für alle Betrieb.

Einfach und Dummy-Weg - speichern Sie Ihre Daten in temporäre Datei und senden Sie diese Datei:)

Die Boost-Serialisierung-Archive können mit jedem Stream gebaut werden. So kann jeder oarchive jede Ostream verwenden, und jede iArchive jede istream verwenden können. So können Sie auf einen Ostringstream archivieren, übertragen Sie die Zeichenfolge mit Asio und rekonstruieren die Daten aus, dass.

Sehen Sie die Referenz von binary_oarchive hier , zum Beispiel.

Ich vermute, Sie werden zunächst in dem Speicher zu archivieren, und dann, dass an die Buchse schreiben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top