Archived

This topic is now archived and is closed to further replies.

evilchicken

advanced serialization

Recommended Posts

evilchicken    122
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.

Share this post


Link to post
Share on other sites
Dire.Wolf    122
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

Share this post


Link to post
Share on other sites
evilchicken    122
alright I have my

  
#define SERVER_SNAPSHOT 3
typedef 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?

Share this post


Link to post
Share on other sites
Dire.Wolf    122
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 data

packet_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

// #1
snap.clientdata = buffer + 6;

// #2
snap.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

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
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

Share this post


Link to post
Share on other sites