Инкапсуляция данных (сетевое программирование) - PullRequest
5 голосов
/ 28 марта 2011

Я прочитал Введение BG для сетевого программирования, но одна тема не стоит на месте, как сомнительна:. Инкапсуляцию данных
В основном я создаю структуру, которая содержит длину данных и сообщение. Например:

struct Data
{  
    int length;  
    std::string message;  
}

Как я могу отправить его? С помощью функции send() я могу отправлять только переменные типа char *.
Кроме того, когда я отправляю его на стороне сервера, я должен создать динамический буфер длины, указанной инкапсуляцией, и упаковать в него сообщение?

Ответы [ 2 ]

2 голосов
/ 28 марта 2011

Общий подход в 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;

Возможно, вам придется немного буферизовать полученные данные, пока чтение из потока не будет успешным.

0 голосов
/ 28 марта 2011

Send () принимает символ *, чтобы разрешить отправку любых двоичных данных кратными одному байту.Вы пробовали приводить к символу *?

На приемном конце вы должны распаковать первые несколько байтов, чтобы узнать длину.Конечно, этот подход предполагает, что отправитель и получатель используют одинаковые длины.Вы также должны внимательно относиться к аргументам упаковки, которые вы отправляете компилятору.

...