2

Well I want to send commands and data between client and server.

I have three projects:

  • Client
  • Server
  • Common - here I put common classes and network abstraction layer

I am using following data structures for communications between client and server

public class Packet<T>
{
        public string Name { get; set; }
        public string From { get; set; }
        public string To { get; set; }
        public PacketType PacketType { get; set; }
        public T Container { get; set; }

        public Packet()
        {
        }

        public Packet(string name, PacketType packetType, T container)
        {
            Name = name;
            PacketType = packetType;
            Container = container;
        }
    }

    public enum PacketType
    {
        Command,
        Data
    }

If I need to send information about files I just create a packet with the necessary structure CreatePacket<FilesInfo>(filesInfo) and then serialize it and send it to client\server.

But how I can deserialize data on receiving side? I don't know what is object type the packet is. Is there any other way or library or something to solve my problem? Also I don't want to use WCF because my app should work on machines with .NET 2.0 installed.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Neir0
  • 12,849
  • 28
  • 83
  • 139

4 Answers4

3

Both chrfin and haiyyu have the same and a good idea. Below is the minor twist of using a Packet Base class to hold your type data on construction. You serialize a Packet< T > and deserialize to a Packet. Use is pretty simple then. Still the trick as already mentioned is to make the Type easily accessible.

class Program
{
    static void Main(string[] args)
    {
        var pack = new Packet<int>() { Payload = 13 };
        var serializedData = pack.Serialize();
        var deserializedData = Packet.Deserialize(serializedData);
        Console.WriteLine("The payload type is:" + deserializedData.PayloadType.Name);
        Console.WriteLine("the payload is: " + deserializedData.Payload);
        Console.ReadLine();
    }
}



[Serializable]
public class Packet
{
    public Type PayloadType { get; protected set; }
    public object Payload { get; protected set; }
    public static Packet Deserialize(byte[] bytes)
    {
        return (Packet)(new BinaryFormatter()).Deserialize(new MemoryStream(bytes));
    }
}

[Serializable]
class Packet<T> : Packet
{
    public Packet()
    {
        PayloadType = typeof(T);
    }
    public new T Payload 
    {
        get { return (T)base.Payload; } 
        set { base.Payload = value; } 
    }

    public override string ToString()
    {
        return "[Packet]" + Payload.ToString();
    }

    public byte[] Serialize()
    {
        MemoryStream m = new MemoryStream();
        (new BinaryFormatter()).Serialize(m, this);
        return m.ToArray();
    }
}
deepee1
  • 12,878
  • 4
  • 30
  • 43
2

Both the server and the client application have to use the same type. The sender can then tell the receiver the type of the data as a string, the receiver will then be able to get the type using Type.GetType().

haiyyu
  • 2,194
  • 6
  • 22
  • 34
2

You could encapsulate the paket in a container which also contains the type:

public class Container
{
    public Type PacketType { get; set; }
    public byte[] Packet { get; set; }
}

and then

Container c = (Container)cSerializer.Deserialize(/*Your Received Packet*/);
Packet<c.PacketType> paket = 
    (Packet<c.PacketType>)pSerializer.Deserialize(new MemoryStream(c.Packet));

or you could require that T always extens a Base-class and then use that on the receiving side:

Packet<BaseClass> paket = 
    (Packet<BaseClass>)pSerializer.Deserialize(new MemoryStream(/*Data*/));
Christoph Fink
  • 22,727
  • 9
  • 68
  • 113
0

If you are useing XML serialization, this seems to work well....

private string GetClassNameFromXMLSerializedString(string xml)
    {
        xml = xml.Substring(xml.IndexOf(">\r\n<") + 3, 50);//get second XML element
        return xml.Substring(1, xml.IndexOf(' ') - 1);//get class name
    }
SnowMan50
  • 7
  • 2