Cramming data into a single stream

Started by
30 comments, last by DividedByZero 16 years, 11 months ago
Hi there, How would you go about cramming required data from a class into a single stream to send as a packet. For example; class player { int id; char *name; float posX; float posY; //....etc. } How can you put this into a stream to send, possibly separating with $ or something and encapsulating with [ & ] to show where data starts and ends. [101$Lonewolff$67.5321$99.0953] << Just an example The way I have been doing this in the past is extremely hacky and cumbersome and usually results in separate sends. Any help would be greatly appreciated.
Advertisement
You know the size of all the types except strings, so you cna just pack the data in raw form (4 bytes usually for an int, etc). For the string, I'd send a 2 or 4 byte length, then the string itself.

Does the stream have to be text? Binary data will be much more efficient and means you don't need to tokenise it on the recieveing end.

My code would look something like:
std::vector<unsigned char> vDataStream;player thePlayer; // Contains data to packPack(vDataStream, &thePlayer.id, sizeof(int))size_t nameLen = strlen(thePlayer.name);Pack(vDataStream, &nameLen, sizeof(size_t))Pack(vDataStream, thePlayer.name, nameLen)Pack(vDataStream, &thePlayer.posX, sizeof(float))Pack(vDataStream, &thePlayer.posY, sizeof(float))Send(vDataStream);

I would probably resort to boost::serialization.

EDIT: a short illustration:

// The class definition...class player {  // Easier to handle than a C string  std::string name;   // Other members here ...  // Serialization function  template<class Archive>  void serialize(Archive & ar, const unsigned int)  {      ar & id;    ar & name;    ar & posX;    ar & posY;  }};
I'd recommend serialization.

You may use that technique for saving/loading to/from files and inter-process communication. Some garbage collectors traverse the object graph using Serialization. It's multi-functional.

cu,
Chris
Quote:Original post by Christian Weis
Some garbage collectors traverse the object graph using Serialization.


Which, how, and why? I know that both garbage collection and serialization take advantage of each other (because they use the same form of reflection), but it seems a stretch to say garbage collection uses serialization.

Thanks for your very quick replies, guys!

[Evil Steve]
That is exactly what I was looking for. I understand what you have done here.
Although, where does the Pack() function come from? I am not familiar with this one. What include file would I need for this?

[ToohrVyk]
I often see Boost come up in GameDev. I haven't ever used the boost library. I might have to have a look at it one day.

Man! More replies.

You guys are posting too quick :)
Thanks heaps, btw.

Oh, Evil Steve.
Is there an Unpack() function for the other end? Server side?
Quote:You know the size of all the types except strings, so you cna just pack the data in raw form (4 bytes usually for an int, etc)...

First off don't make this assumption, one sides sizeof(int) maybe 4 bytes other maybe 8 and boom, your data is now corrupt. So use fixed sized types, uint32 for most platforms and unsigned __int32 for MS.(why dont they have stdint.h????)

This is how I would do it.
Make it nice and simple by defining the insertion and extraction operator for your stream class, then use a serialising help which insert the actual data. Define a pack and unpack for each structure you want to send. Also save bytes and know your data . Do the IEEE floats need to use 32 bits? are they normals? are they within a range? Does the id need to 32 bits? do you actually need to send the data(a simple flag can determine this). If you use a flag how big will it be? the same size as a char and is this required?

So maybe you want to create a bitstream instead of a byte stream.
Your packing can then look something like:
bitbuffer <<someclass;
which internally may do
bitbuffer <<some_int <<some_float <<some_other_float <<some_flag ....

[edit]
There is an article about this one of the game programming series, cant remember the correct book it maybe 6 or 5?
Check out the forum faqs, q12 q15 and q22.
Quote:Original post by ToohrVyk
Quote:Original post by Christian Weis
Some garbage collectors traverse the object graph using Serialization.


Which, how, and why? I know that both garbage collection and serialization take advantage of each other (because they use the same form of reflection), but it seems a stretch to say garbage collection uses serialization.


Well, the GC in my scripting language per example. And the GC of UnrealScript. It's documented somewhere in thier script reference, but cannot remember where.

cu,
Chris

Quote:Original post by Christian Weis
Well, the GC in my scripting language per example.


How, and why? [wink]

This topic is closed to new replies.

Advertisement