Initiate Mage
- Joined
- Aug 5, 2008
- Messages
- 25
- Reaction score
- 3
This is a simple serializing, de serializing objects tutorial, i think this tutorial will give you a bit of a good start on understanding serializing and experimenting with data transfers, there are several great libraries out there like protobuf NET.
The reason i am writing this very simple thing is because when i remember my self several years ago trying to understand how things work, i always found extremely thorough and complex examples and tutorials, i personally belong to a group of people who like straight to the point things, i prefer reading small tutorials of everything and then just connecting the knowledge from each tutorial.
NOTE: READ THE COMMENTS IN THE CODE
Step 1: Understanding the basics!!
Our serializing class, serializer.cs (you can remove the singleton pattern if you wish)
Our packets.cs, we use Structs over classes here because in general structs consume less heap memory, but its ultimately up to you. Performance is always subjective on what you want to achieve, you can try both structs and classes and benchmark them.
Now you can compile it as a dll for example and distribute it with both the client and the server applications.
TestConsoleApp.cs - Just a console app that tests our DLL ;-), what it does is writing a .bin file in our currently working directory with our serialized object and then read it and output the de serialized data. Don't forget to compile our previous example as a class library "Example.dll" then add reference in our TestConsoleApp Project
Step 2: Going a bit deeper!!
To be continued! I will be giving some examples with sockets, serializing and encryption here and maybe some multi threading, hopefully tomorrow
The reason i am writing this very simple thing is because when i remember my self several years ago trying to understand how things work, i always found extremely thorough and complex examples and tutorials, i personally belong to a group of people who like straight to the point things, i prefer reading small tutorials of everything and then just connecting the knowledge from each tutorial.
NOTE: READ THE COMMENTS IN THE CODE
Step 1: Understanding the basics!!
Our serializing class, serializer.cs (you can remove the singleton pattern if you wish)
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace Example
{
public class Serializer
{
//our thread safe singleton implementation
private static object synching = new Object();
private static Serializer instance;
private Serializer() { }
public static Serializer Instance
{
get
{
if (instance == null) {
//locks the instance
lock (synching)
{
if (instance == null) { instance = new Serializer(); }
}
}
return instance;
}
}
public String serialize(Object obj)
{
/* our binary formatter ([URL="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter.aspx"]Check this[/URL]) and memory stream ([URL="http://msdn.microsoft.com/en-us/library/system.io.memorystream.aspx"]Check this[/URL]) objects */
BinaryFormatter bf = new BinaryFormatter();
MemoryStream memStr = new MemoryStream();
try {
bf.Serialize(memStr, obj);
//now the memorystream has the binary formated object every time we write something into the stream the stream is positioned at the end so that we can continue writing/appending more data to the stream so we have to put it to the starting position that is 0
memStr.Position = 0;
//we convert it to array and return it as a base64string
return Convert.ToBase64String(memStr.ToArray());
}
// the memStr will be closed regardless of what happens in the try statement
finally {
memStr.Close();
}
}
public Object deSerialize(String str)
{
Object obj = new Object();
BinaryFormatter bf = new BinaryFormatter();
MemoryStream memStr = new MemoryStream(Convert.FromBase64String(str));
try {
obj = bf.Deserialize(memStr);
return obj;
}
finally {
memStr.Close();
}
}
}
}
Our packets.cs, we use Structs over classes here because in general structs consume less heap memory, but its ultimately up to you. Performance is always subjective on what you want to achieve, you can try both structs and classes and benchmark them.
Code:
using System;
using System.Collections.Generic;
using System.Text;
namespace Example
{
//just a normal enum
public enum ProtocolWhatEverTypes { protocol1=1, protocol2=2, protocol3=3 }
//the struct has to be tagged as Serializable!
[Serializable]
public struct Request
{
public String id;
public ProtocolWhatEverTypes protocol;
public Request(String _id, ProtocolWhatEverTypes _protocol)
{
id = _id;
protocol = _protocol;
}
}
}
Now you can compile it as a dll for example and distribute it with both the client and the server applications.
TestConsoleApp.cs - Just a console app that tests our DLL ;-), what it does is writing a .bin file in our currently working directory with our serialized object and then read it and output the de serialized data. Don't forget to compile our previous example as a class library "Example.dll" then add reference in our TestConsoleApp Project
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using Example;
namespace ConsoleApplication_Serializing
{
class TestConsoleApp
{
static void Main(string[] args)
{
Console.WriteLine("CHOOSE PROTOCOL 1, 2 ,3 (if you type anything else the protocol will by default 3): ");
ProtocolWhatEverTypes protocol;
String readLineProtocol = Console.ReadLine();
if (readLineProtocol == "1")
{
protocol = ProtocolWhatEverTypes.protocol1;
}
else if (readLineProtocol == "2")
{
protocol = ProtocolWhatEverTypes.protocol2;
}
else
{
protocol = ProtocolWhatEverTypes.protocol3;
}
Console.WriteLine("\n\nWRITE ANYTHING: ");
Request testRequest = new Request( Console.ReadLine(), protocol);
String serializedStr = Serializer.Instance.serialize( testRequest );
Console.WriteLine(" \n\n\n\n SERIALIZED: " + serializedStr + "\n\n\n" );
Write(serializedStr);
Object deserializedTest = Serializer.Instance.deSerialize(Read());
Request testRequest_new = (Request) deserializedTest;
Console.WriteLine("DESERIALIZED: " + testRequest_new.id.ToString() + " Protocol: " + testRequest_new.protocol.ToString());
while (true)
{
Thread.Sleep(500);
}
}
public static void Write(String data)
{
TextWriter tw = new StreamWriter( Directory.GetCurrentDirectory() + "//test_object_serialize.bin");
tw.WriteLine(data);
tw.Close();
}
public static String Read()
{
String str;
TextReader tr = new StreamReader( Directory.GetCurrentDirectory() + "//test_object_serialize.bin");
str = tr.ReadToEnd();
tr.Close();
return str;
}
}
}
Step 2: Going a bit deeper!!
To be continued! I will be giving some examples with sockets, serializing and encryption here and maybe some multi threading, hopefully tomorrow