2010-03-31 155 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