2013-02-28 25 views
1

我有服務器和客戶端應用程序,它們通過NetworkStream進行通信。在服務器上,我使用二進制序列化對象並通過NetworkStream發送它,它在客戶端讀取並反序列化。但它拋出錯誤: 二進制流'0'不包含有效的BinaryHeader。可能的原因是序列化和反序列化之間無效的流或對象版本更改。 首先我檢查了NetworkStream的長度,發送序列化對象後服務器和客戶端的長度是一樣的。然後我添加一個服務器引用到客戶端,並使用Server.SaveData來確保在反序列化時我有完全相同的類。二進制流'0'不包含有效的BinaryHeader

然後我試着序列化和反序列化,然後服務器上的相同對象和下面的代碼完美地工作。

stream.Read(buffer, 0, total); 
network_stream.Write(buffer, 0, total); 

network_stream.Read(buffer, 0, total); 
stream.Position = 0; 
stream.Write(buffer, 0, total); 

SaveData savedata = (SaveData)formatter.Deserialize(stream); 

下面是來自服務器全碼:

Stream stream = new MemoryStream(); 
IFormatter formatter = new BinaryFormatter(); 

current_state.saveData(map, red, blu); 
formatter.Serialize(stream, current_state); 

int total = (int)stream.Length; 
byte[] buffer = new byte[total]; 

writer.WriteLine(total.ToString()); 
writer.Flush(); 

stream.Read(buffer, 0, total); 
network_stream.Write(buffer, 0, total); 

stream.Close(); 

和客戶端:

Stream stream = new MemoryStream(); 
IFormatter formatter = new BinaryFormatter(); 

while (reader.Peek() == '\0') { reader.Read(); } //solved the problem, idkw 
int total = Convert.ToInt32(reader.ReadLine().ToString()); 
byte[] buffer = new byte[total]; 

network_stream.Read(buffer, 0, total); 
stream.Position = 0; 
stream.Write(buffer, 0, total); 
stream.Position = 0; 

Console.Write(stream.Length.ToString()); 

Server.SaveData current_state = (Server.SaveData)formatter.Deserialize(stream); //here is the problem 

stream.Close(); 
+0

你無法用另一個應用程序序列化的'BinaryFormatter'反序列化數據,或者您是否有問題來傳遞序列化的二進制流或什麼? – Sinatr 2013-02-28 11:51:58

+0

客戶端和服務器使用相同版本的.net? – Andy 2013-02-28 11:52:20

+0

另外,這是一個基於UDP或TCP的流?你確定接收端有完整的數據集嗎? – Andy 2013-02-28 11:55:33

回答

0

爲什麼不序列化/數據反序列化直接向NetworkStream(無中間MemoryStream)?

一個小例子。

假設,有一個服務器和客戶端用來交換的數據結構(在你的情況下數據結構是current_state)。

[Serializable] 
public class UserData : ISerializable 
{ 
    public string Text { get; private set; } 
    public int Number { get; private set; } 

    public UserData(string text, int number) 
    { 
     Text = text; 
     Number = number; 
    } 

    protected UserData(SerializationInfo info, StreamingContext context) 
    { 
     Text = info.GetString("Text"); 
     Number = info.GetInt32("Number"); 
    } 

    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("Text", Text); 
     info.AddValue("Number", Number); 
    } 
} 

要發送的數據結構(從客戶端爲例):

using (var networkStream = tcpClient.GetStream()) 
{ 
    var userData = new UserData("Hello.", 9); 

    var binaryFormatter = new BinaryFormatter(); 
    binaryFormatter.Serialize(networkStream, userData); 
} 

要接收的數據結構(服務器端爲例):

var binaryFormatter = new BinaryFormatter(); 
using (var networkStream = tcpClient.GetStream()) 
{ 
    while (networkStream.DataAvailable) 
    { 
     var receivedData = (UserData)binaryFormatter.Deserialize(networkStream); 
    } 
} 
相關問題