Reputation: 13367
Well I want to send commands and data between client and server.
I have three projects:
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.
Upvotes: 2
Views: 6116
Reputation: 7
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
}
Upvotes: 0
Reputation: 13196
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();
}
}
Upvotes: 4
Reputation: 23103
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*/));
Upvotes: 2
Reputation: 2242
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().
Upvotes: 2