二进制格式化程序从内存流冻结中反序列化
binary formatter deserialize from memory stream freezing
我正在尝试做一个通过套接字进行通信的客户端-服务器应用程序,它们的消息是序列化的,并使用 BinaryFormatter 反序列化。我的代码冻结并且在反序列化时完全没有做任何事情,我不明白为什么,因为我没有例外。我也无法进入调试器,一切都冻结了。这是我的代码:
public class Serializer
{
public static MemoryStream ToStream(object obj)
{
var stream = new MemoryStream();
var formatter = new BinaryFormatter();
formatter.Serialize(stream, obj);
return stream;
}
public static object FromStream(MemoryStream stream)
{
Console.WriteLine("Starting from stream");
var formatter = new BinaryFormatter();
stream.Seek(0, SeekOrigin.Begin);
object rez = formatter.Deserialize(stream); //NEVER GOES OVER THIS
Console.WriteLine("Starting deserialization" + rez);
return formatter.Deserialize(stream);
}
}
public class Connection
{
private Socket socket;
public Connection(Socket socket)
{
this.socket = socket;
Console.WriteLine($"Connected to client: {socket.RemoteEndPoint}");
Task.Factory.StartNew(() => Execute(socket));
}
private void Execute(Socket socket)
{
while (true)
{
var buffer = new byte[2048];
var bytesCount = socket.Receive(buffer);
if(bytesCount != 0)
{
var msgReceived = (Message)Serializer.FromStream(new MemoryStream(buffer, 0, buffer.Length));
Console.WriteLine($"Received msg: {msgReceived.Content}");
}
/* var msg = new Message { Content = "Hello World2!" };
Console.WriteLine($"Sending msg with content: {msg.Content}");
MemoryStream stream = Serializer.ToStream(msg);
var bytesSent = socket.Send(stream.GetBuffer());*/
Console.WriteLine("Trying again");
Thread.Sleep(500);
}
}
客户代码:
var host = Dns.GetHostEntry("localhost");
var ipAddress = host.AddressList.First();
var serverEndpoint = new IPEndPoint(ipAddress, 9000);
Socket serverSocket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Connect(serverEndpoint);
Console.WriteLine($"Successfully connected to server on: {serverSocket.RemoteEndPoint}");
while (true)
{
var msg = new Message { Content = "Hello World!" };
Console.WriteLine($"Sending msg with content: {msg.Content}");
MemoryStream stream = Serializer.ToStream(msg);
var bytesSent = serverSocket.Send(stream.GetBuffer());
Console.WriteLine("Waiting to receive");
var buffer = new byte[2048];
int bytesReceived = serverSocket.Receive(buffer);
if (bytesReceived != 0)
{
var receivedMessage = (Message)Serializer.FromStream(new MemoryStream(buffer));
Console.WriteLine($"Received message: {receivedMessage.Content}");
}
Console.WriteLine("Received done");
}
服务器代码:
var host = Dns.GetHostEntry("localhost");
var ipAddress = host.AddressList.First();
var localEndPoint = new IPEndPoint(ipAddress, 9000);
var serverSocket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(localEndPoint);
serverSocket.Listen(1);
while (true)
{
Console.WriteLine("Waiting for client");
Socket clientSocket = serverSocket.Accept();
var connection = new Connection(clientSocket);
}
我也检查了 byteCount 并且它们正在到达服务器,缓冲区也不是空的,我不明白为什么反序列化什么都不做..
只有一段代码可以同时运行。虽然无限循环 while (true)
运行s,但没有其他代码能够 运行.
您需要向该项目添加一些多任务处理。每个文字处理器所需的最低数量。但是,您似乎也在控制台中进行编程。根据我的经验,控制台和多任务处理不能很好地结合。您需要让程序保持活动状态,而不阻塞输入。
我对学习多任务处理的建议是 Windows Forms 中的 BackgroundWorker。 BGW 已过时,使用这些线程在这里是不必要的,不应在生产代码中使用。但它可能是我所知道的最好的多任务处理和多线程处理 "Training Wheels"。
你调用了两次 Deserialize,我认为问题在这里:
object rez = formatter.Deserialize(stream); //NEVER GOES OVER THIS
Console.WriteLine("Starting deserialization" + rez);
return formatter.Deserialize(stream);
我想你可以使用这样的方法:
private byte[] SerializeMessage(Message msg)
{
var formatter = new BinaryFormatter();
byte[] buf;
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, msg);
buf = new byte[stream.Length];
return stream.ToArray();
}
}
private Message DeserializeMessage(byte[] buff)
{
var formatter = new BinaryFormatter();
ConnectingMessage msg;
using (Stream stream = new MemoryStream(buff))
{
msg = formatter.Deserialize(stream) as Message;
}
return msg;
}
方法 Send/Receive 也是同步的,它们会阻止线程执行。
我正在尝试做一个通过套接字进行通信的客户端-服务器应用程序,它们的消息是序列化的,并使用 BinaryFormatter 反序列化。我的代码冻结并且在反序列化时完全没有做任何事情,我不明白为什么,因为我没有例外。我也无法进入调试器,一切都冻结了。这是我的代码:
public class Serializer
{
public static MemoryStream ToStream(object obj)
{
var stream = new MemoryStream();
var formatter = new BinaryFormatter();
formatter.Serialize(stream, obj);
return stream;
}
public static object FromStream(MemoryStream stream)
{
Console.WriteLine("Starting from stream");
var formatter = new BinaryFormatter();
stream.Seek(0, SeekOrigin.Begin);
object rez = formatter.Deserialize(stream); //NEVER GOES OVER THIS
Console.WriteLine("Starting deserialization" + rez);
return formatter.Deserialize(stream);
}
}
public class Connection
{
private Socket socket;
public Connection(Socket socket)
{
this.socket = socket;
Console.WriteLine($"Connected to client: {socket.RemoteEndPoint}");
Task.Factory.StartNew(() => Execute(socket));
}
private void Execute(Socket socket)
{
while (true)
{
var buffer = new byte[2048];
var bytesCount = socket.Receive(buffer);
if(bytesCount != 0)
{
var msgReceived = (Message)Serializer.FromStream(new MemoryStream(buffer, 0, buffer.Length));
Console.WriteLine($"Received msg: {msgReceived.Content}");
}
/* var msg = new Message { Content = "Hello World2!" };
Console.WriteLine($"Sending msg with content: {msg.Content}");
MemoryStream stream = Serializer.ToStream(msg);
var bytesSent = socket.Send(stream.GetBuffer());*/
Console.WriteLine("Trying again");
Thread.Sleep(500);
}
}
客户代码:
var host = Dns.GetHostEntry("localhost");
var ipAddress = host.AddressList.First();
var serverEndpoint = new IPEndPoint(ipAddress, 9000);
Socket serverSocket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Connect(serverEndpoint);
Console.WriteLine($"Successfully connected to server on: {serverSocket.RemoteEndPoint}");
while (true)
{
var msg = new Message { Content = "Hello World!" };
Console.WriteLine($"Sending msg with content: {msg.Content}");
MemoryStream stream = Serializer.ToStream(msg);
var bytesSent = serverSocket.Send(stream.GetBuffer());
Console.WriteLine("Waiting to receive");
var buffer = new byte[2048];
int bytesReceived = serverSocket.Receive(buffer);
if (bytesReceived != 0)
{
var receivedMessage = (Message)Serializer.FromStream(new MemoryStream(buffer));
Console.WriteLine($"Received message: {receivedMessage.Content}");
}
Console.WriteLine("Received done");
}
服务器代码:
var host = Dns.GetHostEntry("localhost");
var ipAddress = host.AddressList.First();
var localEndPoint = new IPEndPoint(ipAddress, 9000);
var serverSocket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(localEndPoint);
serverSocket.Listen(1);
while (true)
{
Console.WriteLine("Waiting for client");
Socket clientSocket = serverSocket.Accept();
var connection = new Connection(clientSocket);
}
我也检查了 byteCount 并且它们正在到达服务器,缓冲区也不是空的,我不明白为什么反序列化什么都不做..
只有一段代码可以同时运行。虽然无限循环 while (true)
运行s,但没有其他代码能够 运行.
您需要向该项目添加一些多任务处理。每个文字处理器所需的最低数量。但是,您似乎也在控制台中进行编程。根据我的经验,控制台和多任务处理不能很好地结合。您需要让程序保持活动状态,而不阻塞输入。
我对学习多任务处理的建议是 Windows Forms 中的 BackgroundWorker。 BGW 已过时,使用这些线程在这里是不必要的,不应在生产代码中使用。但它可能是我所知道的最好的多任务处理和多线程处理 "Training Wheels"。
你调用了两次 Deserialize,我认为问题在这里:
object rez = formatter.Deserialize(stream); //NEVER GOES OVER THIS
Console.WriteLine("Starting deserialization" + rez);
return formatter.Deserialize(stream);
我想你可以使用这样的方法:
private byte[] SerializeMessage(Message msg)
{
var formatter = new BinaryFormatter();
byte[] buf;
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, msg);
buf = new byte[stream.Length];
return stream.ToArray();
}
}
private Message DeserializeMessage(byte[] buff)
{
var formatter = new BinaryFormatter();
ConnectingMessage msg;
using (Stream stream = new MemoryStream(buff))
{
msg = formatter.Deserialize(stream) as Message;
}
return msg;
}
方法 Send/Receive 也是同步的,它们会阻止线程执行。