How would you send binary data over web?

What I am wondering is, how would one send binary data over the web to a web server? I was following along with Mike Geig’s “Data persistence” live training which talks about using serialization and the BinaryFormatter to save player data to local files on your device. He had mentioned that you could probably send it through a POST Request to a web server. I was just curious as how to do that.

It seems the BinaryFormatter.Serialize() function wants to send an object map to a stream. As I can tell, the WWW class sends a URL request, but I’m not sure if it behaves the same as like an IO stream.

I’m guessing you couldn’t do something like this:


    BinaryFormatter bf = new BinaryFormatter();
    WWW www = new WWW("http://test.url.com/test.php");
    bf.Serialize(www, playerData);

I’m just wondering how to go about doing this. What I want to be able to do is send player information to a server to be saved into a database table for the player (inventory, player stats). I’d love to be able to send the data in a similar manner as I would saving a binary file. I guess one option would be to save the binary locally, then send it through the WWWForm.AddBinaryData method. I was just wondering if there is some direct way to serialize through the BinaryFormatter and send via HTTP.

The answer is don’t use HTTP.

HTTP stands for “Hypertext Transfer Protocol”. It is a single push/fetch text protocol layered ontop of TCP/IP which is a connected in-order guaranteed binary protocol. if you want to send and receive binary packets TCP/Ip is whole lot more efficient.

The one advantage of HTTP is that it can traverse most firewalls. Websockets brings in the ability to make a connection as if you were an HTTP request but then upgrade and maintain the connection as a straight TCP/IP connection, which is the best of both worlds.

To use Websockets you need a server that supports them and a client library for them on your client computer. Such libraries are available for C++ on the web.

To directly answer your question, if you’d like to specifically use HTTP, use a WWWForm with a MemoryStream and BinaryFormatter as you’re suggesting above.

Something like this (C#):

// Create the memory stream:
MemoryStream theStream=new MemoryStream();

// Create a formatter:
BinaryFormatter format=new BinaryFormatter();

// Serialize into the memory stream:
format.Serialize(theStream,playerData);

// Create the form:
WWWForm form=new WWWForm();

// Add the stream data to your form:
form.AddBinaryData("post-field-name",theStream.ToArray(), "filename.bytes", "application/octet-stream");

// Upload:
WWW www = new WWW("http://test.url.com/test.php",form);

Having said that, I wouldn’t recommend this approach at all! The main reasoning is updates. For example, you might introduce a new feature into your game which results in your player data object gaining fields or loosing fields. When using straight serialization, this has a nasty habit of corrupting your save data. A better approach is to create either specific fields in your database, and map each one to a post field, or alternatively create a textual (XML, config, JSON) storage format and use that instead, or as another alternative, use BinaryReader/BinaryWriter and construct the binary object yourself - this way you can at least be aware of the exact structure of your binary data, and how flexible it is to things like adding a new bit of data to it without it breaking all your players existing saves.

That’s before mentioning the security aspects of this approach too. Don’t forget that as soon as someone discovers which URL to send requests to, something which is fairly straight forward to do, it becomes really easy to give their account a few “upgrades” :slight_smile: This should be considered with any storage system of course, but especially with ones over HTTP due to the open nature of the web. You’ll want to create some form of key exchange system so you can verify requests too.