Общий подход в C ++ состоит в предоставлении функций, которые могут сериализовать ваш пользовательский тип в любой объект «потока», а затем предоставить способ получить указатель на начало блока данных, который был накоплен в потоке.
Простым примером этого является std :: ostringstream, который можно использовать для сериализации данных в поток, а затем получить указатель на созданную строку:
int i = 13;
std::string message = "Hi";
std::ostringstream stream;
stream << i << message;
cout << stream.str() << endl; // prints "13Hi";
Вы можете сделать то же самое для вашего типа Data
, предоставив соответствующие перегрузки операторов <<
и >>
, например:
std::ostringstream &operator<<( std::ostringstream &stream, const Data &v ) {
return stream << v.length << v.message;
}
std::ostringstream &operator>>( std::ostringstream &stream, Data &v ) {
return stream >> v.length; >> v.message;
}
Используя эти функции, вы можете сделать это:
Data myData = { 13, "Hello" };
std::ostringstream stream;
stream << myData;
const std::string serializedData = stream.str();
send( .., serializedData.c_str(), serializedData.size() + 1, .. );
По размеру получения вы можете прочитать данные в буфер и затем использовать объект std::istringstream
для повторного извлечения данных:
const char receivedData[ 1024 ];
// fill receivedData array using recv()
std::string s = receivedData;
std::istringstream stream( s );
Data myData;
stream >> myData;
Возможно, вам придется немного буферизовать полученные данные, пока чтение из потока не будет успешным.