ダブルスのリストを:SerializationException
から逆シリアル化しようとすると、常に取得し続けます。NetworkStream
解析が完了する前にストリームの終わりが検出されました
私は単純なクライアントサーバーアーキテクチャを持っていますTcpTransportClient
。aの機能をラップし、 (メッセージを送信する)と(メッセージが受信されるまでブロックする)のTcpClient
2つの基本的な方法を利用します。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();
}
Receive
のメソッドでメッセージを逆シリアル化しようとすると常に例外が発生しますTcpTransportClient
が、データセットにデータを入れた場合にのみ問題が発生します。ネットワークを介して値のリストを送信し、受信側でそれらを正常に逆シリアル化する適切な方法は何ですか?
PSほぼ同じ質問で解決策を試しましたが、うまくいきませんでした。それでも同じ例外が発生します。