Как отправить список структурной структуры через сокет с клиента на сервер в C ++ (проблема сериализации)?

0

У меня две структуры, а первая - как список во втором:

struct SType{
  int Num;
  char Word[20];
  char sugg[20];
};


struct DataPktType
{
    list<SType> MyList;
    char filename[MAX_SIZE];
    int numslaves;
};

Я знаю, что для сериализации есть ускорение и библиотека google, но я хочу отправить эти данные на специальный сервер, который не позволяет устанавливать boost и т.д.
Поэтому я должен сделать это вручную. Я видел и протестировал простой ответ на этом веб-сайте для сериализации и десериализации вручную qaru.site/questions/687440/.... По мере того как я испытал это работает отлично с собственной структурой. Тем не менее, это для простой структуры, и, как вы видели, у меня есть список во второй структуре. список имеет разный размер времени.
Я ценю, если кто-нибудь может показать какой-то пример или намек. В настоящее время я отправляю struct over socket таким образом, что вызвало ошибку сегментации!

// Write and read a message to/from the server 
write(Sockfd, (char*)&DataPkt, sizeof(DataPktType));
read(Sockfd, (char*)&recDataPkt, sizeof(DataPktType));
  • 0
    Отправка памяти на фоне структуры, содержащей механику динамического выделения ( list<SType> ), никогда не будет работать. И почему тег C на этот вопрос? Вы должны отправлять байты, так или иначе, а не указатели на платформе. Этого не избежать. Что еще хуже, вы также должны учитывать платформенность ваших многобайтовых интегралов. Все это является частью магии использования механики консервированных сериализаций, таких как boost и google protobuffs.
  • 0
    Не делай этого. Не используйте структуры в качестве сетевых протоколов. Используйте сетевые протоколы в качестве сетевых протоколов. Вы вводите как минимум шесть зависимостей, которые должны быть идентичны на обоих концах, чтобы это работало. Определите себе сетевой протокол в байтах, затем напишите себе библиотеку для отправки и получения.
Показать ещё 1 комментарий
Теги:
struct
sockets
client-server

1 ответ

0
Лучший ответ

Я "вручную" сделал что-то похожее на то, что, как я подозреваю, вы хотите сделать.

Для непростого типа (DataPktType) вы можете рассмотреть следующий грубый контур (только для того, чтобы помочь вам начать работу).

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

restore() был, в некотором смысле, обратным для store().

struct SType{
  int Num;
  char Word[20];
  char sugg[20];

  virtual void store(ostream& os);
  virtual void restore(istream& is);
};


struct DataPktType
{
  list<SType> MyList;
  char filename[MAX_SIZE];
  int numslaves;

  virtual void store(ostream& os);
  virtual void restore(istream& is);
};

Итак, где DataPktType.store() может передавать каждый атрибут данных POD в поток:

DataPktType::store(ostream& os)
{
   os << MyList.size(); // gotta know how many to extract later

   for (auto it = myList.begin(); myList.end(); it++)
   {
      it->store(os); // tell the SType to store itself at this point in the stream
   }

   os << filename;
   os << numslaves;
}

Тогда "обратный" может быть чем-то вроде

DataPktType::restore(istream& is)
{
   size_t listSize = 0;
   is >> listSize;  
   // input error checks

   for(size_t i=0; i<listSize; ++i)
   {
      SType listItem;

      listItem.restore(is); // assumes the list item contents are 'next' in the file

      MyList.push_back(listItem); // I don't use std::list often, 
      // there seems to be several choices for adding to a list
   }

   is >> filename;
   is >> numslaves;
}

Это те вещи, которые, я думаю, вам нужно делать.

Обратите внимание, что указатели не входят в потоки.

Обратите внимание, что симметрия не идеальна, но вам нужно будет выяснить, как обращаться с каждым действием.

В моих усилиях, я считаю, я добавил несколько простых проверок на этом пути...

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

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

У нас были некоторые сжатые сроки, и в конечном итоге он выбрал двоичный код ввода-вывода. Но мы просто проверяли текст ввода-вывода.

Удачи.

PS - мы в конце концов добавили номер версии для содержимого store/restore, чтобы поддерживать изменения структуры во время эволюции кода проекта.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню