advanced serialization

Started by
5 comments, last by evilchicken 22 years, 5 months ago
hello, what is the best way of sending an linked list or an array with serialization? thanks.
Advertisement
I built an array of MAX_SIZE and stuck it inside a structure. I zeromemory''ed the array before adding content to it. however it seems the entire array is sent causing a buffer overrun.
Assuming homogenous elements in the list, one way you can do it is to have a header:

struct SerializedListHeader
{
int count;
int element_size;
char* data;
};

Allocate a chunk of memory that is equal to the size of the elements in your list multiplied by the number of nodes. Then loop through each node of your list, copying the node to the appropriate data array offset. The offset is calculated by:

data[current_node_count * element_size];

so you can do a memcopy:

memcpy(&data[current_node_count * element_size], &nodedata, sizeof(nodedata));

The complication comes when the elements aren''t homogenous or you are serializing classes. Then each class needs to support a serialized() method that either a) returns a char stream or b) accepts a char pointer to a buffer and serializes directly to that buffer:

a) std::string serialize() const
b) void serialize(char* stream) const

When calling method b) you''d pass the indexed data pointer:

someclass->serialize(&data[current_node_count * element_size]);


This is just off the top of my head, so I hope it is useful



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
alright I have my

  #define SERVER_SNAPSHOT			3typedef struct{	BYTE	type;	BYTE	numClients;	float	timestamp;		BYTE	*clientdata;}packet_server_snapshot_t;typedef struct{	BYTE clientid,		 energy;	float xpos,		  ypos,		  xvel,		  yvel;	short orientation;}send_snap_t;  


and on the server I have
packet_server_snapshot_t sendSnap;
send_snap_t tempSnap;

sendSnap.clientdata = new BYTE[num_nodes * sizeof(tempSnap)];

and I loop thru the nodes and do a
memcpy(&sendSnap.clientdata[current_node * sizeof(tempSnap)], &tempSnap, sizeof(tempSnap));

then I serialize sendSnap and send it away.

on the client I have this

send_snap_t temp;

and loop thru the array copying the data like this.

memcpy(&temp, &snap.clientdata[current_node * sizeof(temp)], sizeof(temp));


the client memcpy code crashes, what am I doing wrong?

EDIT:
-----

I just re-read your post. Let me see if I understand what you are trying to do:

1. Server serializes client info (send_snap_t) into an array pointed to by sendSnap.clientdata.

2. The server then sends this information to the client.

3. The client receives this data in a buffer (char buffer of some arbitrary length)

4. The client takes this data buffer and copies 6 bytes (BYTE, BYTE, FLOAT) to a variable named 'snap' which is of type packet_server_snapshot_t.

5. The client then allocated memory for snap.clientdata to hold the remaining received data. The size of this array is snap.numClients * sizeof(send_snap_t).

6. The client then copies the data from the buffer into the newly allocated BYTE array pointed to by snap.clientdata.

7. The client then attempts to extract each 'send_snap_t' contained withing snap.clientdata and put the data into a variable named 'temp' of type 'send_snap_t'.

If this is correct, my guess is that:

You might not have allocated the memory for the received data structures before calling memcpy on snap.clientdata or snap.clientdata doesn't point to the correct address.

AND/OR

You might not have received all the data you need.

For example:

char buffer[2000];recv(s, buffer, 2000, 0);// make sure you received the required amount of datapacket_server_snapshot_t snap;memcpy(&snap, buffer, 6);  // assume 6 bytes for simplicity here// now you have two ways to get the serialized client data// #1snap.clientdata = buffer + 6;// #2snap.clientdata = new BYTE[snap.numClients * sizeof(send_snap_t)];memcpy(snap.clientdata, buffer + 6, snap.numClients * sizeof(send_snap_t));// now you should have the correct memory pointers etc.send_snap_t temp;for(int idx = 0; idx < snap.numClients; ++idx){    memcpy(&temp, &snap.clientdata[idx * sizeof(send_snap_t)], sizeof(send_snap_t));    // do something with 'temp'} 


That should work...let me know if it doesn't.

Best regards,


Dire Wolf
www.digitalfiends.com

Edited by - Dire.Wolf on October 26, 2001 4:54:43 PM
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
cool, however Im doing a compete rewrite of the client right now, and I wont be able to try this out until later, thank for your help thou
cool, however Im doing a compete rewrite of the client right now, and I wont be able to try this out until later, thank for your help thou

This topic is closed to new replies.

Advertisement