Jump to content
  • Advertisement
Sign in to follow this  
DividedByZero

Cramming data into a single stream

This topic is 4249 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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 pack
Pack(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);


Share this post


Link to post
Share on other sites
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;
}
};

Share this post


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

Share this post


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

Share this post


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

Share this post


Link to post
Share on other sites
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?

Share this post


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

Share this post


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

Share this post


Link to post
Share on other sites
Quote:
Original post by Christian Weis
Well, the GC in my scripting language per example.


How, and why? [wink]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!