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.
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;