www.digitalmars.com         C & C++   DMDScript  

c++ - How to serialize to binary data for TCP/IP communication

reply "Masterchief" <ronald.putz kapsch.net> writes:
Hy!

I am searching a tutorial which shows me how I can serailia a C++ class to 
binary data to send it over the network and deserialze it at the receiver.
Does anyone have an example or link?

Ronny 
Jan 24 2007
parent reply Bertel Brander <bertel post4.tele.dk> writes:
Masterchief skrev:
 Hy!
 
 I am searching a tutorial which shows me how I can serailia a C++ class to 
 binary data to send it over the network and deserialze it at the receiver.
 Does anyone have an example or link?
If you know what you are doing, you can simply cast a pointer to an object of the class to a void pointer and send that, using sizeof to get the size of the object. At the receiver, simply do the opposite. But beware of pointers in the class and virtual tables. Also note that no constructor for the class is called. If this is not an option, you need to do it by hand. Either: 1: serialize and deserialize each data member. 2: Describe each class in at text file that can be converted to a .h file with the class definition and to functions that can serialize and deserialize the class. The first method will do if you have a small number of classes that do not change frequently. For the second method you need to develop at tool that can parse the text files and create the two output files, that should be easy. -- Just another homepage: http://damb.dk But it's mine - Bertel
Jan 24 2007
parent reply "Masterchief" <ronald.putz kapsch.net> writes:
HY!

I tried your suggestion with the cast to void*.
I did this a few days ago, but it failed. But with your hint I could figure 
out my error.
I had a char* in my Message class and this caused the error, should mean the 
class was not correct assembled at recv.

IŽhave changed it now to the following members:

class BaseMessage : public DynamicListElement

{

public:

enum MessageType

{

NO_MSG = 0,

BASE_MSG,

UNDEF_MSG

};

BaseMessage();

~BaseMessage();



<SNIP>

private:

//char* mData;

BaseMessageItemList mList;

char mHeader[MESSAGE_HEADER_LENGTH];

static unsigned long mMessageId;

unsigned long mDataLen;

unsigned long mAnswerId;

//char* mSender;

//struct hostent mSender;

char mSender[256];

MessageType mType;

};

BaseMessageItemList is an array of 20 BaseMessageItem s.

Send is done the following way:
BaseMessage *lMess = new BaseMessage();

BaseMessageItem it2;

it2.setId(333);

lMess->addElement(it2);

int ret = send(mSocket,

(const char*)(void*)lMess,

lSize,

MSG_DONTROUTE);


Recv is done the following:

BaseMessage* lRecvMes = new BaseMessage();

int rlen = recv(piSocket,

(char*)(void*)lRecvMes,

sizeof(BaseMessage),

0);

My question now is can I change the BaseMessageItemList to a pointered List?
YouŽll quess IŽve already tryed it and it didnŽt work:-(
Do you have any suggestions?


Thanks








"Bertel Brander" <bertel post4.tele.dk> schrieb im Newsbeitrag 
news:ep8mfp$e4l$1 digitaldaemon.com...
 Masterchief skrev:
 Hy!

 I am searching a tutorial which shows me how I can serailia a C++ class 
 to binary data to send it over the network and deserialze it at the 
 receiver.
 Does anyone have an example or link?
If you know what you are doing, you can simply cast a pointer to an object of the class to a void pointer and send that, using sizeof to get the size of the object. At the receiver, simply do the opposite. But beware of pointers in the class and virtual tables. Also note that no constructor for the class is called. If this is not an option, you need to do it by hand. Either: 1: serialize and deserialize each data member. 2: Describe each class in at text file that can be converted to a .h file with the class definition and to functions that can serialize and deserialize the class. The first method will do if you have a small number of classes that do not change frequently. For the second method you need to develop at tool that can parse the text files and create the two output files, that should be easy. -- Just another homepage: http://damb.dk But it's mine - Bertel
Jan 25 2007
parent reply Bertel Brander <bertel post4.tele.dk> writes:
Masterchief skrev:
 HY!
 
 I tried your suggestion with the cast to void*.
 I did this a few days ago, but it failed. But with your hint I could figure 
 out my error.
 I had a char* in my Message class and this caused the error, should mean the 
 class was not correct assembled at recv.
 
 IŽhave changed it now to the following members:
 
 class BaseMessage : public DynamicListElement
 
 {
 
 public:
 
 enum MessageType
 
 {
 
 NO_MSG = 0,
 
 BASE_MSG,
 
 UNDEF_MSG
 
 };
 
 BaseMessage();
 
 ~BaseMessage();
 
 
 
 <SNIP>
 
 private:
 
 //char* mData;
 
 BaseMessageItemList mList;
 
 char mHeader[MESSAGE_HEADER_LENGTH];
 
 static unsigned long mMessageId;
 
 unsigned long mDataLen;
 
 unsigned long mAnswerId;
 
 //char* mSender;
 
 //struct hostent mSender;
 
 char mSender[256];
 
 MessageType mType;
 
 };
 
 BaseMessageItemList is an array of 20 BaseMessageItem s.
 
 Send is done the following way:
 BaseMessage *lMess = new BaseMessage();
 
 BaseMessageItem it2;
 
 it2.setId(333);
 
 lMess->addElement(it2);
 
 int ret = send(mSocket,
 
 (const char*)(void*)lMess,
 
 lSize,
 
 MSG_DONTROUTE);
 
 
 Recv is done the following:
 
 BaseMessage* lRecvMes = new BaseMessage();
 
 int rlen = recv(piSocket,
 
 (char*)(void*)lRecvMes,
 
 sizeof(BaseMessage),
 
 0);
 
 My question now is can I change the BaseMessageItemList to a pointered List?
 YouŽll quess IŽve already tryed it and it didnŽt work:-(
 Do you have any suggestions?
What is the type of BaseMessageItemList? If it is a simple array, it should work. What is DynamicListElement? The "static unsigned long mMessageId;" could be a problem. -- Just another homepage: http://damb.dk But it's mine - Bertel
Jan 25 2007
parent reply "Masterchief" <ronald.putz kapsch.net> writes:
Hy!

<SNIP>

 My question now is can I change the BaseMessageItemList to a pointered 
 List?
 YouŽll quess IŽve already tryed it and it didnŽt work:-(
 Do you have any suggestions?
What is the type of BaseMessageItemList? If it is a simple array, it should work.
This is exactly the point. Usually it was an Pointer List => didnŽt work. Then I changed it to an array => works fine
 What is DynamicListElement?
Is a generic class. Actually it was an item of the pointer list now its just a class where I can store data: class BaseMessageItem { public: BaseMessageItem(); ~BaseMessageItem(); int getId() { return mMTXId; } void setId(int piId) { mMTXId = piId; } private: int mMTXId; }; But this is the point I want to solve. I wanted to use a poiter list in my message class.
 The "static unsigned long mMessageId;" could be a problem.
With the static Message ID I donŽt have any problems. What could be the problem you think? Thanks
 -- 
 Just another homepage:
 http://damb.dk
 But it's mine - Bertel 
Jan 25 2007
parent reply Bertel Brander <bertel post4.tele.dk> writes:
Masterchief skrev:
 Hy!
 
 <SNIP>
 
 My question now is can I change the BaseMessageItemList to a pointered 
 List?
 YouŽll quess IŽve already tryed it and it didnŽt work:-(
 Do you have any suggestions?
What is the type of BaseMessageItemList? If it is a simple array, it should work.
This is exactly the point. Usually it was an Pointer List => didnŽt work. Then I changed it to an array => works fine
I have done an attempt to do it in another way. Here you declare the class as: CLASS(SomeClass) DECLARE(int, x) DECLARE_ARRAY(20, int, array) DECLARE_POINTER(len, ptr, short) END_CLASS The preprocessor will translate it into tree things. First the class: class SomeClass { public: bool Deserialize(Deserializer& ser); bool Serialize(Serializer& ser) const; int x; int array[20]; int len; short* ptr; }; The preprocessor will also create the two functions Serialize and Deserialize for you. The len parameter specifies the number of elements in ptr. I have put everything in a .zip file: http://damb.dk/zip/serialize.zip -- Just another homepage: http://damb.dk But it's mine - Bertel
Jan 27 2007
parent "Masterchief" <ronald.putz kapsch.net> writes:
Thanks a lot!


"Bertel Brander" <bertel post4.tele.dk> schrieb im Newsbeitrag 
news:epgk1l$2ivg$1 digitaldaemon.com...
 Masterchief skrev:
 Hy!

 <SNIP>

 My question now is can I change the BaseMessageItemList to a pointered 
 List?
 YouŽll quess IŽve already tryed it and it didnŽt work:-(
 Do you have any suggestions?
What is the type of BaseMessageItemList? If it is a simple array, it should work.
This is exactly the point. Usually it was an Pointer List => didnŽt work. Then I changed it to an array => works fine
I have done an attempt to do it in another way. Here you declare the class as: CLASS(SomeClass) DECLARE(int, x) DECLARE_ARRAY(20, int, array) DECLARE_POINTER(len, ptr, short) END_CLASS The preprocessor will translate it into tree things. First the class: class SomeClass { public: bool Deserialize(Deserializer& ser); bool Serialize(Serializer& ser) const; int x; int array[20]; int len; short* ptr; }; The preprocessor will also create the two functions Serialize and Deserialize for you. The len parameter specifies the number of elements in ptr. I have put everything in a .zip file: http://damb.dk/zip/serialize.zip -- Just another homepage: http://damb.dk But it's mine - Bertel
Jan 28 2007