views:

3907

answers:

5

I have a data structure that looks like this:

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

I want to use boost::serialization to serialize this data structure, then use boost::asio to transmit it via TCP/IP, then have another application receive the data and de-serialize it using the same boost libraries.

I'm trying to following boost::serialization tutorial, (as some other SO questions have suggested) but the example is specifically for writing/reading to a file, not to a socket using boost::asio.

I'm pretty sure I've got the right tools for the job -- I just need help making them work together. Writing to a socket can't be that different from writing to a file, right?

Any suggestions are very much appreciated. Thanks!

+1  A: 

You doing serialization to boost::archive which get constructor parameter - destination stream, where you will save data. You could use boost.iostreams library for define your own stream which will send data over network, instead file or just use asio socket streams (http://www.boost.org/doc/libs/1_36_0/doc/html/boost_asio/reference/ip__tcp/iostream.html). It is a good way, we did something similar on this, but we have few streams (zip/encrypt/send) and used boost iostreams library for all operation.

Easy and dummy way - store your data in temporary file and send this file :)

bb
+3  A: 

There is a good serialization example in the asio documentation: server.cpp, stock.hpp, connection.hpp.

Here's a snippet:

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);
hvintus
+1  A: 

I suspect you'll want to archive to memory first, and then write that to the socket.

Matt Cruikshank
+1  A: 

The boost serialization archives can be constructed with any stream. Thus any oarchive can use any ostream, and any iarchive can use any istream. Thus you can archive to an ostringstream, transmit the string with asio, and reconstruct the data from that.

See the reference of binary_oarchive here, for example.

rlbond
i think you meant 'any iarchive can use any istream'
David Claridge
I sure did!~!!!
rlbond
+1  A: 

For such simple structure, boost::serialization is overkill and huge overhead.

Do simpler:

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[3]);

And Save yourself HUGE overhead that boost::serialization has

And if you private protocol where computers with same order of bytes work (big/little) that just send structure as is -- POD.

Artyom
I definitely agree with you about the overhead of boost::serialization. It turned my tiny data structure into something that was almost 50 bytes larger!
Runcible
This does not answer the question of how it is generally possible to send serialized data over network (connecting Boost Serialization and Asio). This just answers the question of how to send the specific struct via Boost::Asio
MOnsDaR