C++ 使用Boost序列化和发送数据结构?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/652193/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Serialize and send a data structure using Boost?
提问by Runcible
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.
我想使用 boost::serialization 来序列化这个数据结构,然后使用 boost::asio 通过 TCP/IP 传输它,然后让另一个应用程序接收数据并使用相同的 boost 库反序列化它。
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.
我正在尝试遵循 boost::serialization 教程,(正如其他一些 SO 问题所建议的那样),但该示例专门用于写入/读取文件,而不是使用 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!
任何建议都非常感谢。谢谢!
采纳答案by Artyom
For such simple structure, boost::serialization is overkill and huge overhead.
对于这样简单的结构, boost::serialization 是矫枉过正和巨大的开销。
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[2]);
And Save yourself HUGE overhead that boost::serialization has
并为自己节省 boost::serialization 的巨大开销
And if you private protocol where computers with same order of bytes work (big/little) that just send structure as is -- POD.
如果您使用具有相同字节顺序的计算机工作(大/小)的私有协议,则按原样发送结构 - POD。
回答by hvintus
There is a good serialization examplein the asio documentation: server.cpp, stock.hpp, connection.hpp.
asio 文档中有一个很好的序列化示例: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);
回答by Tymek
I thought I'd share this with anyone who was trying to serialize a C++ struct
using Boost. For the example given above, to make the struct
serializable you would add a serialize
function:
我想我会与任何试图struct
使用 Boost序列化 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;
回答by Peter Jankuliak
EDIT: I take back my answer below, what I proposed does have the time and space advantages over the stringstream solution but the asio::stream API is lacking some important functionality that will be needed in a long run (e.g. timed interruption).
编辑:我收回下面的答案,我提出的与 stringstream 解决方案相比确实具有时间和空间优势,但是 asio::stream API 缺少一些长期需要的重要功能(例如定时中断)。
My original answer:
我的原答案:
Use streams from boost::asio, it has time and space advantages over writing it into std::stringstreams and then sending it in one go. Here is how:
使用来自 boost::asio 的流,与将其写入 std::stringstreams 然后一次性发送相比,它具有时间和空间优势。方法如下:
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());
And then, after you are connected with either client or server stream just do:
然后,在您与客户端或服务器流连接后,只需执行以下操作:
MyDataType obj;
// Send the object.
boost::archive::text_oarchive archive(stream);
archive << obj;
// Or receive it.
boost::archive::text_iarchive archive(stream);
archive >> obj;
You of course need to add the 'serialize' function into your MyDataType as Tymek wrote in his answer.
您当然需要将“序列化”功能添加到您的 MyDataType 中,正如 Tymek 在他的回答中所写的那样。
回答by rlbond
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.
可以使用任何流构建 boost 序列化档案。因此,任何 oarchive 都可以使用任何 ostream,任何 iarchive 都可以使用任何 istream。因此,您可以存档到 ostringstream,使用 asio 传输字符串,并从中重建数据。
See the reference of binary_oarchive here, for example.
例如,请参阅此处的 binary_oarchive 参考。
回答by bayda
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.
您对 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)并且所有操作都使用 boost iostreams 库。
Easy and dummy way - store your data in temporary file and send this file :)
简单而虚拟的方式 - 将您的数据存储在临时文件中并发送此文件:)
回答by Matt Cruikshank
I suspect you'll want to archive to memory first, and then write that to the socket.
我怀疑您首先要存档到内存中,然后将其写入套接字。