23

次のようなデータ構造があります。

typedef 構造体
{
  unsigned short m_short1;
  unsigned short m_short2;
  unsigned char m_character;
} MyDataType;

boost::serialization を使用してこのデータ構造をシリアライズし、boost::asio を使用して TCP/IP 経由で送信し、別のアプリケーションにデータを受信させ、同じブースト ライブラリを使用してデシリアライズしたいと考えています。

私はboost::serializationのチュートリアルに従おうとしていますが(他のSOの質問が示唆しているように)、この例は特にboost::asioを使用したソケットではなく、ファイルへの書き込み/読み取り用です。

私は仕事に適したツールを持っていると確信しています.それらを連携させるための助けが必要です. ソケットへの書き込みは、ファイルへの書き込みとそれほど違いはありませんよね?

どんな提案でも大歓迎です。ありがとう!

4

7 に答える 7

31

asio のドキュメントに良いシリアル化の例があります: server.cppstock.hppconnection.hpp

ここにスニペットがあります:

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);
于 2009-03-16T21:54:20.070 に答える
27

structBoost を使用して C++ をシリアライズしようとしている人と共有したいと思いました。上記の例では、structシリアライズ可能にするには、serialize関数を追加します。

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;
于 2011-07-26T20:25:50.690 に答える
4

編集:私は以下の私の答えを取り戻します、私が提案したものは文字列ストリームソリューションよりも時間とスペースの利点がありますが、asio :: stream APIには長期的に必要となるいくつかの重要な機能が欠けています(例えば、時限中断)。


私の最初の答え:

boost :: asioからのストリームを使用します。これは、std :: stringstreamsに書き込んでから一度に送信するよりも、時間とスペースに利点があります。方法は次のとおりです。

クライアントコード:

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

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

サーバーコード:

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()); 

次に、クライアントストリームまたはサーバーストリームのいずれかに接続した後、次の手順を実行します。

MyDataType obj;

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

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

もちろん、Tymekが回答に書いたように、MyDataTypeに「serialize」関数を追加する必要があります。

于 2011-11-21T23:05:08.460 に答える
1

ブースト シリアライゼーション アーカイブは、任意のストリームで構築できます。したがって、任意の oarch は任意の ostream を使用でき、任意の iarchive は任意の istream を使用できます。したがって、ostringstream にアーカイブし、asio で文字列を送信し、そこからデータを再構築できます。

たとえば、こちらの binary_oarchive のリファレンスを参照してください。

于 2009-03-16T22:08:37.290 に答える
1

コンストラクターパラメーターを取得するboost::archiveにシリアル化を行います-データを保存する宛先ストリーム。ファイルの代わりにネットワーク経由でデータを送信する独自​​のストリームを定義するために、boost.iostreams ライブラリを使用するか、単に asio ソケット ストリームを使用することができます ( http://www.boost.org/doc/libs/1_36_0/doc/html/boost_asio/参照/ip__tcp/iostream.html )。これは良い方法です。同様のことを行いましたが、ストリーム (zip/encrypt/send) はほとんどなく、すべての操作にブースト iostream ライブラリを使用しました。

簡単でダミーの方法-データを一時ファイルに保存し、このファイルを送信します:)

于 2009-03-16T21:50:11.000 に答える
-1

最初にメモリにアーカイブしてから、それをソケットに書き込みたいと思うでしょう。

于 2009-03-16T21:56:21.937 に答える