Reputation: 83
I need to send a structure of different data types at once through UDP. I have tried using the boost library, but I am unable to send all the structure elements at once. Here is a snippet of the structure I need to send:
struct sample {
char a;
char16_t b;
char c;
std::string d;
char e;
};
sample mystruct;
Creating a string concatenating every element doesn't work for me because I am sending hexadecimal values which should not be converted to string. This is the method I am using for sending the information through the socket:
sock.send_to(boost::asio::buffer(&mystruct, sizeof(mystruct)), remote, 0, error);
This is not working because there is additional data that is being sent. I only want to send the elements of the struct, without separation or any kind of data between them.
Thanks in advance.
Upvotes: 1
Views: 1818
Reputation: 2937
Sending and receiving structures over network sockets (no mater what type of the socket you are using synchronous or asynchronous TCP, datagram UDP ) logical similar to file read/write. It means - simply dumping the memory approach is not going to work, especially when you structure contains class/structure fields or pointers. Usually serialization approach used instead, e.g. you can serialize you structure into some binary (ASN1, Google Protocol Buffers etc) or text format (XML,JSON,YAML etc) - send the result by network, receive it and de-serialize back to a structure.
You can use boost serialization for serialization propose.
I.e. something like:
#include <boost/archive/text_oarchive.hpp>
....
struct sample {
char a;
char16_t b;
char c;
std::string d;
char e;
};
namespace boost {
namespace serialization {
template<class Archive>
void serialize(Archive & ar,const sample& value, const unsigned int version)
{
ar & value.a;
ar & value.b;
ar & value.c;
ar & value.d;
ar & value.e;
}
} // namespace serialization
} // namespace boost
...
sample mystruct;
....
std::ostringstream archive_stream;
boost::archive::text_oarchive archive(archive_stream);
archive << mystruct;
...
sock.send_to( boost::asio::buffer(archive_stream.str()), remote, 0, error);
Then you can de-serialize the structure, when received
#include <boost/archive/text_iarchive.hpp>
....
std::string str;
str.resize(1024);
boost::asio::udp::endpoint sender_endpoint;
std::size_t len = socket.receive_from(
boost::asio::buffer(str), sender_endpoint);
....
std::istringstream archive_stream(str);
sample mystruct;
boost::archive::text_iarchive archive(archive_stream);
archive >> mystruct;
Upvotes: 1
Reputation: 26136
That is not going to work. You can only send raw data through a connection since ASIO does not perform any serialization. std::string
is not a trivial type and also contains members (like pointers) that do not make sense to send over a connection. Further, a structure may not be portable between computers of different kinds.
You will have to use something like the Boost Serialization library, Protobuffers or a similar library; or perform similar duties yourself.
Upvotes: 0