0

I have two struct and first one is defined as a list in second one:

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


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

I know there is boost and google library for serialization but I want to send this data over an special server which does not allow to install boost etc.
So I have to do it manually. I have seen and tested a simple answer on this website to serialize and deserialize manually https://stackoverflow.com/a/20838004/1679519. As I tested this is working fine with its own structure. However, it is for a simple struct and as you have seen I have a list in the second struct. list has a different size time to time.
I appreciate if anyone can show some example or hint. Currently I send the struct over socket in this way which caused segmentation fault!

// Write and read a message to/from the server 
write(Sockfd, (char*)&DataPkt, sizeof(DataPktType));
read(Sockfd, (char*)&recDataPkt, sizeof(DataPktType));
Community
  • 1
  • 1
Bernard
  • 4,240
  • 18
  • 55
  • 88
  • Sending the memory backdrop of a structure that contains dynamic allocation mechanics (`list`) is *never* going to work. And why is the C tag on this question? You have to send bytes, one way or another, not platform-side pointers. There is no escaping that. Making matter worse, you also need to account for platform-endianness of your multibyte integrals. All this is part of the magic of using canned serialization mechanics like boost and google protobuffs. – WhozCraig Jun 06 '14 at 18:54
  • Don't do this. Don't use structs as network protocols. Use network protocols as network protocols. You are introducing at least six dependencies which need to be identical at both ends for this to work. Define yourself a network protocol, in bytes, then write yourself a library to send and receive it. – user207421 Jun 07 '14 at 00:29
  • 1
    You need to write serialization and deserialization code if you want to serialize and deserialize a structure. You are expecting it to happen by magic. – David Schwartz Jun 07 '14 at 00:44

1 Answers1

0

I have 'manually' done something similar to what I suspect you want to do.

For the non-simple type (DataPktType) you might consider the following crude outline (if only to help get you started).

First, I added 2 virtual methods to all classes that needed to participate - in my case, we called them store and restore. These methods dealt only with the data attributes of their own class.

restore() was, in some sense, the inverse of 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);
};

So, where DataPktType.store() might transfer every POD data attribute into the ostream:

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

Then, the 'inverse' might be something like

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

These are the kinds of things I think you need to do.

Notice no pointers go into the streams.

Notice that the symmetry is not perfect, but you will have to figure out how to handle each action.

In my effort, I believe I added some simple checks along the way ...

Also, my team used text for the first implementation. As a human, that will be much easier to debug, and you can use an editor to debug 'symmetry' issues.

Furthermore, you may find that the text i/o performance is adequate, and thus just leave it as text.

We had some tight deadlines, and ultimately chose the binary i/o. But we kept the text i/o simply to test.

Good luck.

PS - we eventually added a 'version' number for the contents of store/restore, to support struct changes during evolution of the project code.

2785528
  • 5,438
  • 2
  • 18
  • 20