C# 通过TCP发送大型对象:“;解析完成前遇到的流结束";
每当我试图从C# 通过TCP发送大型对象:“;解析完成前遇到的流结束";,c#,serialization,tcp,tcpclient,C#,Serialization,Tcp,Tcpclient,每当我试图从网络流中反序列化双工列表时,我总是收到一个序列化异常: 之前遇到的流结束 解析已完成 我有一个简单的客户机-服务器体系结构:我的TcpTransportClient包装了TcpClient的功能,我使用了两种基本方法:Send(发送消息)和Receive(直到收到消息为止) 发送函数接收一条消息,使用二进制格式化程序对其进行序列化,并通过网络流发送字节 public void Send(Message message) { if (message == null) {
网络流中反序列化双工列表时,我总是收到一个序列化异常
:
之前遇到的流结束
解析已完成
我有一个简单的客户机-服务器体系结构:我的TcpTransportClient
包装了TcpClient
的功能,我使用了两种基本方法:Send
(发送消息)和Receive
(直到收到消息为止)
发送
函数接收一条消息
,使用二进制格式化程序
对其进行序列化,并通过网络流
发送字节
public void Send(Message message)
{
if (message == null)
{
throw new TransportException("Invalidate Parameter In Send Call");
}
if (_tcpClient == null || !_tcpClient.Connected)
{
throw new TransportException("Client Not Connected");
}
lock (_sync)
{
// Serialzie the message
MemoryStream memStream = new MemoryStream();
_serializer.Serialize(memStream, message);
// Get the bytes of of the memory stream
byte[] buffer = memStream.GetBuffer();
// Write the message to the network stream
NetworkStream networkStream = _tcpClient.GetStream();
networkStream.Write(buffer, 0, buffer.Length);
networkStream.Flush();
}
}
接收函数从网络流
将字节读入缓冲区,然后使用二进制格式化程序对消息进行反序列化:
public Message Receive()
{
if (_tcpClient == null || !_tcpClient.Connected)
{
throw new TransportException("Client Not Connected");
}
byte[] buffer;
MemoryStream memStream = new MemoryStream();
NetworkStream netStream = _tcpClient.GetStream();
try
{
do
{
// Allocate a new buffer
buffer = new byte[_tcpClient.ReceiveBufferSize];
// Read the message buffer
int sizeRead = netStream.Read(buffer, 0, buffer.Length);
// Write the buffer to the memory stream
memStream.Write(buffer, 0, sizeRead);
} while (netStream.DataAvailable);
// Reset the memory stream position
memStream.Position = 0;
// Deserialize the message
object tmp = _deserializer.Deserialize(memStream); // <-- The exception is here!
// Cast the object to a message
return (Message)tmp;
}
catch (System.Exception e)
{
if (_tcpClient == null || !_tcpClient.Connected)
{
throw new TransportException("Client Not Connected");
}
else
{
throw e;
}
}
}
当我尝试在我的TcpTransportClient
的Receive
方法中对消息进行反序列化时,总会出现异常,但只有在数据集中放入一些数据时才会出现问题。通过网络发送值列表并在接收端成功反序列化它们的正确方法是什么
顺便说一句,我尝试了一个解决方案,但没有成功:我仍然得到同样的异常
while(netStream.DataAvailable)
那是不对的。当Read()调用返回0时,应该停止读取。DataAvailable属性只是告诉您Read()调用是否会阻塞,等待服务器赶上。您需要。好吧,Read blocks,所以我从未让它返回0。它永远不会脱离while循环。如果保持连接打开,则必须首先发送列表的长度。接收器可以读取此长度,然后将确切知道要读取多少字节()。
TcpTransportClient client = new TcpTransportClient(GetLocalAddress(), servicePort);
client.Connect();
Thread sendThread = new Thread(() =>
{
List<double> dataSet = new List<double>();
for (double d = 0.0; d < 500.0; d++)
{
dataSet.Add(d);
}
while (true)
{
try
{
// Serialize the data set
MemoryStream memStream = new MemoryStream();
BinaryFormatter binFormat = new BinaryFormatter();
binFormat.Serialize(memStream, (object)dataSet);
// Create a message
Message msg = new Message();
// Hold the object bytes in an opaque field
msg.SetFieldValue(1000, memStream.GetBuffer());
// Set the message topic
msg.SetTopic("client.dataSet");
// Send the message
client.Send(msg);
// Sleep
Thread.Sleep(3000);
}
catch (TransportException)
{
break;
}
catch(Exception)
{
//ignore it
}
}
});
sendThread.IsBackground = true;
sendThread.Start();
public void HandleAcceptedClient(TcpTransportClient client)
{
Thread receiveThread = new Thread(() =>
{
while (true)
{
try
{
Message msg = client.Receive();
Trace.WriteLine("Server Received: " + msg.GetTopic());
byte[] buffer = msg.GetFieldOpaqueValue(1000);
MemoryStream memStream = new MemoryStream(buffer);
BinaryFormatter binFormat = new BinaryFormatter();
List<double> dataSet = (List<double>)binFormat.Deserialize(memStream);
if (dataSet.Count == 500)
{
Trace.WriteLine(DateTime.Now + ": OK");
}
else
{
Trace.WriteLine(DateTime.Now + ": FAIL");
}
}
catch (TransportException)
{
break;
}
catch(Exception)
{
// ignore it
}
}
});
receiveThread.IsBackground = true;
receiveThread.Start();
}