Advertisement

How to send boost::archive::text_oarchive with socket?

Started by July 14, 2015 02:43 PM
5 comments, last by Kuxe1 9 years, 4 months ago

I'm confused about sending serialized classes using boost. I currently have a socket class with a method send (which I coded following gafferongames tutorials):


bool send(const IpAddress& destination, const void* data, int size);

It's used for sending some arbitrary data to another machine (usually a packet class).

Currently I have this code for sending packets:


ofstream fs("text.txt");
boost::archive::text_oarchive toa(fs);
toa & packet;

//Send the packet
socket.send({127, 0, 0, 1, serverPort}, &fs, sizeof(fs));

and this code for receiving packets:


auto fs = *(ifstream*)socket.getBuffer();

boost::archive::text_iarchive tia(fs);
Packet<DataType> typedPacket;
tia & packet;

I think this code signals my intent: I want to serialize the variable 'packet', send it to localhost, read the received data, deserialize it into another variable 'packet' on the receiving machine.

socket.getBuffer() contains whatever was passed to the const void* data parameter in send().

There are some problems with this code.. I don't want to create a file "text.txt".. But I serialization step crashes if I create the fs as ofstream fs(nullptr);.

The main thing that I am confused about is, what should I pass as the data-parameter in send()? fs or toa or something else? Id love it if there were something such as toa.getPointerToContentOfThisArchive() and toa.getSizeOfContentInThisArchive()because those I could use to send over network.. hmm.. Any help or suggestions is welcome!

Use std::ostringstream instead. It has a str method in which you can get or set its contents. From there, send the resulting string's length bytes from its c_str as a packet.
Advertisement
There are some problems with this code.. I don't want to create a file "text.txt".. But I serialization step crashes if I create the fs as ofstream fs(nullptr);.

text_archive takes an ostream, not neccessarily an ofstream. The latter is an "output file" stream, and consequently if you don't want to create a file, you shouldn't use an "output file" stream; ofstream expects a valid filename in the constructor, which nullptr isn't, thus the crashes.
As fastcall says, an ostringstream or some other ostream implementation that doesn't involve file IO is probably want you want.
ofstream fs("text.txt");
...
socket.send({127, 0, 0, 1, serverPort}, &fs, sizeof(fs));
At the risk of seeming harsh, I would suggest that this code shows to me that you do not yet have an understanding of C++, pointers, and memory, that is necessary to successfully build a networking layer.
I suggest that you spend another year or two doing C++ development on a local machine/host/game, to the point where you actually understand things like memory layout of objects, cost of disk versus cost of memory, and other such important concepts. Then perhaps try again for something networked.
enum Bool { True, False, FileNotFound };

Use std::ostringstream instead. It has a str method in which you can get or set its contents. From there, send the resulting string's length bytes from its c_str as a packet.

Thank you, just what I was looking for!


ofstream fs("text.txt");
...
socket.send({127, 0, 0, 1, serverPort}, &fs, sizeof(fs));
At the risk of seeming harsh, I would suggest that this code shows to me that you do not yet have an understanding of C++, pointers, and memory, that is necessary to successfully build a networking layer.
I suggest that you spend another year or two doing C++ development on a local machine/host/game, to the point where you actually understand things like memory layout of objects, cost of disk versus cost of memory, and other such important concepts. Then perhaps try again for something networked.

I did realize that code wouldn't work; I didn't know there were streams that didn't require output files - so I had so signal my intent as best as I could writing some broken code for this thread. Or was it something else you come to think of that was bad code? Please do tell :)

Or was it something else you come to think of that was bad code?


Yes. You are taking the address of the stream. That's just some class that contains data to manage the stream -- not the actual data of the stream. Trying to send that over a socket makes no sense.

I really do think you would actually move faster towards the end goal if you backed off a bit, and worked more on the fundamentals, and came back to networking once that is firmly in mind.
enum Bool { True, False, FileNotFound };
Advertisement

Or was it something else you come to think of that was bad code?


Yes. You are taking the address of the stream. That's just some class that contains data to manage the stream -- not the actual data of the stream. Trying to send that over a socket makes no sense.

I really do think you would actually move faster towards the end goal if you backed off a bit, and worked more on the fundamentals, and came back to networking once that is firmly in mind.

The whole point was to demonstrate something that wouldn't work, ie &fs or &toa, while signaling intent and then ask what the correct way of sending data via socket would be.

This topic is closed to new replies.

Advertisement