2012-02-07 58 views
0

那麼我想在客戶端和服務器之間發送命令和數據。如果我不知道正確的類型,我該如何反序列化一個對象?

我有三個項目:

  • 客戶
  • 服務器
  • 常見 - 在這裏,我把普通班和網絡抽象層

我使用以下數據結構的客戶端之間的通信和服務器

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 
    } 

如果我需要發送有關文件的信息,我只需創建一個包含必要結構CreatePacket<FilesInfo>(filesInfo)的數據包,然後將其序列化併發送到client \ server。

但我如何反序列化接收端的數據?我不知道數據包是什麼對象類型。有沒有其他方式或圖書館或什麼東西來解決我的問題?另外我不想使用WCF,因爲我的應用程序應該在安裝了.NET 2.0的計算機上工作。

回答

3

chrfin和haiyyu都有相同的 一個好主意。以下是使用Packet Base類來保存構造中的類型數據的細微變化。您將一個數據包序列化並將其反序列化爲一個數據包。然後使用非常簡單。前面已經提到的技巧仍然是讓類型易於訪問。

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(); 
    } 
} 
2

服務器和客戶端應用程序都必須使用相同的類型。然後,發送者可以將接收者的數據類型告訴字符串,然後接收者就可以使用Type.GetType()來獲取類型。

+0

很好的建議。 – Neir0 2012-02-07 15:53:45

1

你可以封裝的一攬子貸款項目,其中也包含了類型的容器:

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

然後

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

,或者你可以要求T總是延長線插頭插座一個基類,然後使用在接收端:

Packet<BaseClass> paket = 
    (Packet<BaseClass>)pSerializer.Deserialize(new MemoryStream(/*Data*/)); 
0

如果您期運用XML序列化,這似乎運作良好....

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 
    } 
相關問題