2011-06-12 45 views
5

我目前正在visual studio 2010測試。我做了一個客戶端和服務器,它們都將通過UdpClient連接。用UdpClient C發送對象#

我想從客戶端發送一個對象到服務器。我有兩種方法將對象轉換爲字節並將其轉換爲對象。現在,當我測試我的應用程序時,我無法將其轉換回服務器上收到的對象

我的服務器發現該對象已收到並試圖將其從字節轉換爲對象,但這會產生錯誤。

System.Runtime.Serialization.SerializationException was unhandled Message=Unable to find assembly 

這似乎是可行的,因爲這兩個應用程序在不同的命名空間......

這是我的方法,將;在客戶端和服務器上都是相同的

public byte[] ToBytes() { 
     using (MemoryStream stream = new MemoryStream()) { 
      BinaryFormatter formatter = new BinaryFormatter(); 
      formatter.Serialize(stream, this); 

      stream.Position = 0; 

      byte[] byteRij = new byte[1024]; 

      stream.Read(byteRij, 0, (int)stream.Length); 

      return byteRij; 
     } 
    } 

    public static Datagram ToDatagram(byte[] rij) { 
     using (MemoryStream stream = new MemoryStream()) { 
      stream.Write(rij, 0, rij.Length); 

      stream.Position = 0; 

      BinaryFormatter formatter = new BinaryFormatter(); 
      return (Datagram)formatter.Deserialize(stream); 
     } 
    } 

我該如何解決這個問題? 在此先感謝

+1

您的'ToBytes()'方法將無法正常工作是序列化形式大於1024字節。爲什麼不使用['ToArray()'方法](http://msdn.microsoft.com/zh-cn/library/system.io.memorystream.toarray.aspx)? – svick 2011-06-12 10:37:49

回答

3

您需要將序列化的所有類放入類庫項目中。在服務器和客戶端都使用該庫。

另請注意,UDP不可靠。不能保證你的信息到達。

+0

請注意,這只是一個BinaryFormatter要求。對於大多數其他序列化程序,您不需要這些。 – 2011-06-12 11:28:53

+0

是的,我想我必須建立一個班級圖書館。這就說得通了。另外,我只是使用UDP來了解我有什麼替代方案。謝謝! – kendepelchin 2011-06-14 11:29:08

1

您可能會遇到不滿意的依賴性問題。這可能是由不同的命名空間或試圖序列化未安裝在服務器上的外部組件引起的。

說:你發送MyApp1.MyFoo類型的對象。
類別MyFoo也在您的服務器中定義,但是作爲MyApp2.MyFoo(這很愚蠢,意味着您必須修復您的設計)。服務器不知道如何創建一個對象MyApp1.MyFoo,因爲它不夠聰明,發現他也定義了這個類,但名爲MyApp2.MyFoo

您應該使用相同的命名空間。這是他們的目的。而且,它們可以更輕鬆地處理依賴關係。和MyApp.Server交談MyApp.Client看起來不錯;)。

我希望你明白這一點。

3

BinaryFormatter與類型元數據緊密相關。這裏不是一個好的選擇,因爲你有不同的類型。其實海事組織它不是一個好的選擇無論如何:)它不是很容忍版本,而且不便攜。

我會在這裏公開推薦protobuf-net(披露:我寫到了)。它是免費的OSS,但使用谷歌的protobuf格式來修復所有的BF問題。設置和使用比較簡單,速度更快,輸出量比BinaryFormatter小。由於它是基於合同的,因此您可以在每一端都有不同的類型,就像他們在合同中所達成的一致(匹配字段號等)一樣。

例如:

[ProtoContract] 
public class Foo { 
    [ProtoMember(1)] 
    public string X {get;set;} 
    [ProtoMember(2)] 
    public int Y {get;set;} 
} 

,然後只用ProtoBuf.Serializer.Serialize(流,對象),以寫入數據。

如果你需要,你也可以不帶屬性地工作,它需要一個更多的設置,但不是很多。