我写了一些代码,这是一个迷你简单模仿信使程序。 在该计划;当用户注销时,我的LogOutCommand类的实例由客户端程序准备,序列化并发送到服务器。当服务器收到LogOutCommand时,它会反序列化并调用类的Execute方法,该方法执行数据库操作等。
问题在于,有时Server可以很好地反序列化,但有时会失败。 据我所知,服务器有时会在完全准确地发送相关字节之前开始反序列化。
如何让服务器以等待所有相关字节完成发送的方式开始反序列化?
或者您认为还有其他问题吗?
以下是代码:
//服务器侦听套接字
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);
}
}
//序列化/反序列化类
public class SerializationHelper
{
public static byte [] Serialize(object obj)
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
尝试
{
formatter.Serialize(stream,obj);
}
catch(例外)
{
MessageBox.Show(“Serialize Edilemiyor”);
}
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;
}
}
答案 0 :(得分:1)
我认为问题在于,一旦数据进入管道,您就会尝试反序列化数据。由于数据包如何通过网络发送,这可能是也可能不可能。
您应该发送带有消息的标头,指示数据的长度(以字节为单位)。然后接收字节,直到该数字被命中并反序列化然后才开始。
您的标题应该是特定的格式并且具有特定的长度,以便在开头时很容易将其删除。
答案 1 :(得分:0)
首先,您不应该使用BinaryFormatter。使用例如更好XmlSerializer的。
其次,请包含您获得的异常详情。