Сериализация класса, содержащего строку, для отправки его по сети через сокет? - PullRequest
0 голосов
/ 30 июня 2019

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

Чтобы идентифицировать сообщения и сериализовать / десериализовать их при отправке через сеть, я создал класс Message, который имеет среди своихчлены std :: string.

Однако у меня возникли проблемы с процессом сериализации.

Для сериализации я использую структуру SerializedMessage:

typedef struct {
    int         iMessageID;
    std::string strText;
} SerializedMessage;

IЗатем хотелось бы создать новый указатель SerializedMessage *, сохранить в нем данные и отправить их через сокет.Хотя я могу легко сохранить идентификатор с помощью функции htonl (), я не знаю, как действовать со строкой.

Пока это мой метод Serialize:

void* Message::Serialize()
{
    SerializedMessage* pSerializedMessage = new SerializedMessage();
    pSerializedMessage->iMessageID = htonl(m_iMessageID);
    //copying the text?
    return (void*)pSerializedMessage;
}

IЯ пытался посмотреть здесь , и это должно ответить на мой вопрос, но я новичок, и я не совсем понимаю, что предлагает мне решение.

Буду очень признателен за некоторую помощь.Спасибо!

1 Ответ

2 голосов
/ 30 июня 2019

Основной причиной проблемы является то, что текстовые строки являются записями переменной длины.

Существует три популярных метода для сериализации строк: 1) длина, за которой следует текст, 2) текст с символом терминатора и 3) фиксированная длина (возможно, с отступом).

Длина, сопровождаемая текстом

Укажите длину текста.
Напиши текст.

+-------------+  
| Text Length |  
+-------------+  
|             |
|    Text     |  
|             |
+-------------+  

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

Символ текста с терминатором (часовым)

Это определение строки в стиле C.

Одна из проблем этого метода заключается в том, что вы не знаете длину, которая делает выделение памяти более утомительной, и вам приходится искать, пока не будет найден символ-терминатор (обычно символ за символом).

Фиксированная длина

Используйте размер блока, который достаточно велик, чтобы вместить наибольшую длину текста, например 4096. Это популярно во многих базах данных. Это компромисс между производительностью и пространством. Блок быстро загружается (читается), потому что это фиксированный размер. Это может привести к потере места, поскольку может быть место, не занятое текстом.

...