2010-03-31 156 views
1

我已經寫了一些代碼,這是一個簡單的模擬messenger程序。 在程序中;當用戶註銷時,我的LogOutCommand類的實例由客戶端程序準備,序列化併發送到服務器。當服務器收到LogOutCommand時,它將反序列化並調用執行數據庫操作的類的Execute方法等。反序列化失敗 - C#

問題是,有時服務器可以很好地反序列化,但有時會失敗。 據我所知,服務器有時會在完全準確地發送關聯字節之前啓動反序列化。

如何使服務器啓動反序列化的方式,它等待所有相關字節完成發送?

或者您認爲還有其他問題?

下面是代碼:

//服務器監聽套接字

private void ReadData(object obj) 
    { 
     Socket client = (Socket)obj; 

     while (true) 
     { 
      if (client.Available > 0) 
      { 
       byte[] buffer = new byte[client.Available]; 
       client.Receive(buffer); 
       ServerCommandBase cmd = CommandReader.ReadSrvCommand(buffer); 
       cmd.Execute(context); 

      } 
     } 
    } 

// CommandReader類

public class CommandReader 
{ 
    public static ServerCommandBase ReadSrvCommand(byte[] buffer) 
    { 
     return (ServerCommandBase)SerializationUtility.SerializationHelper.Deserialize(buffer); 
    } 
    public static ClientCommandBase ReadCliCommand(byte[] buffer) 
    { 
     return (ClientCommandBase)SerializationUtility.SerializationHelper.Deserialize(buffer); 
    } 

} 

//序列化/反序列化類

公共類SerializationHelper { public static byte [] Serialize(object obj) BinaryFormatter formatter = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); 嘗試 formatter.Serialize(stream,obj); (Exceptionize) } catch }
stream.Position = 0; return stream.ToArray(); }

public static object Deserialize(byte[] byteArr) 
    { 
     BinaryFormatter formatter = new BinaryFormatter(); 
     MemoryStream ms = new MemoryStream(byteArr); 
     ms.Position = 0; 
     object retObj = null; 
     try 
     { 
      retObj = formatter.Deserialize(ms); 
     } 
     catch (Exception) 
     { 
      MessageBox.Show("Cannot Be Deserialized!"); 
     } 

     return retObj; 
    } 




} 

回答

1

這個問題,我看到它是你試圖反序列化數據,一旦它的管道。由於數據包是如何通過網絡發送的,這可能會或可能不會。

您應該發送一個包含您的消息的頭文件,以指示數據的長度(以字節爲單位)。然後接着輸入字節,直到那個數字已經被命中,然後反序列化,然後纔開始。

您的標題應該是特定的格式,並且具有特定的長度,以便在開始時很容易將其取下。

+0

Krisc是對的。您需要通過預先發送數據包的大小來執行「消息幀」。然後,您可以針對正確的#個字節發出讀取,然後反序列化該數據包。 有關示例,請參閱http://ferozedaud.blogspot。COM/2009/11 /如何以發送對象,從-Java到net.html。你可以忽略java部分,.NET部分會告訴你如何做消息框架。 – feroze 2010-04-06 22:34:28

0

所有你不應該使用的BinaryFormatter第一。使用例如XmlSerializer的。

其次,請包括你得到的異常細節。

+0

可能是那麼多年過去了,而且發生了很多變化,但我不同意這一點,並且[此答案](https://stackoverflow.com/a/3543963/1003324)解釋了原因。 – 2017-08-07 01:01:59