![](/img/trans.png)
[英]End of Stream encountered before parsing was completed thrown Sending Large Images over UDP Socket
[英]Sending large objects over TCP: “End of Stream encountered before parsing was completed”
每當我嘗試從NetworkStream
反序列化雙精度列表時,我一直收到SerializationException
:
解析完成之前遇到的流結束
我有一個簡單的客戶端服務器架構:我的TcpTransportClient
包含TcpClient
的功能,我使用兩種基本方法: Send
(發送消息)和Receive
(阻塞直到收到消息)。
Send
函數接收Message
,使用BinaryFormatter
對其進行序列化,並通過NetworkStream
發送字節。
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();
}
}
receive函數從NetworkStream
中將字節讀入緩沖區,然后使用BinaryFormatter
對消息進行反序列化:
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 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();
並且只要接受TcpClient
就會啟動一個接收線程:
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();
}
當我嘗試在我的TcpTransportClient
Receive
方法中反序列化消息時,總會發生異常,但只有在數據集中放入一些數據時才會出現問題。 通過網絡發送值列表並在接收端成功反序列化的正確方法是什么?
PS我在一個幾乎相同的問題中嘗試了解決方案,但它沒有用:我仍然得到同樣的例外。
while(netStream.DataAvailable);
那不對。 當Read()調用返回0時,您應該停止讀取.DataAvailable屬性只是告訴您Read()調用是否將阻塞,等待允許服務器趕上。
你需要消息框架 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.