c# - 反序列化通过套接字发送的消息时出现 SerializationException
问题描述
我正在创建一个程序,我试图通过套接字系统连接服务器和多个客户端。出于某种原因,当我反序列化时出现异常。
我这样做是为了使第一条消息的前 2 个字节包含即将到来的消息的长度。(这样我可以接收比缓冲区更大的消息(1024 字节))。我的错误可能与这段代码有关?
例外:
System.Runtime.Serialization.SerializationException:“二进制流“0”不包含有效的 BinaryHeader。可能的原因是无效的流或序列化和反序列化之间的对象版本更改。
基本发送代码如下:
public void Send(byte[] data)
{
if (ClientSocket != null && ClientSocket.Connected)
{
ClientSocket.BeginSend(AddSize(data), 0, data.Length, 0, ResponseSend, this);
}
else
{
ConnectionFailed();
}
}
private byte[] AddSize(byte[] data)
{
var newData = BitConverter.GetBytes(Convert.ToUInt16(data.Length));
Array.Resize(ref newData, sizeof(ushort) + data.Length);
Array.Copy(data, 0, newData, sizeof(ushort), data.Length);
return newData;
}
private void ResponseSend(IAsyncResult ar)
{
try
{
// Complete sending the data to the remote device.
var bytesSent = ClientSocket.EndSend(ar);
SendCompleted();
}
catch (SocketException ex)
{
ConnectionFailed();
}
}
基本接收代码如下:
private const int BufferSize = 1024;
// Receive buffer.
private MemoryStream _bufferStream = new MemoryStream();
private readonly byte[] _buffer = new byte[BufferSize];
private ushort _messageLength;
public void Receive()
{
if (ClientSocket != null && ClientSocket.Connected)
{
ClientSocket.BeginReceive(_buffer, 0, BufferSize, SocketFlags.None, ReceiveCommand, this);
}
else
{
ConnectionFailed();
}
}
private void ReceiveCommand(IAsyncResult ar)
{
// Retrieve the socket from the state object.
var client = (BaseClient)ar.AsyncState;
try
{
var bytesRead = ClientSocket.EndReceive(ar);
if (bytesRead <= 0)
{
ConnectionFailed();
return;
}
var messageSizeOffset = 0;
if (_messageLength == 0)
{
_messageLength = GetMessageLength(client._buffer);
messageSizeOffset = sizeof(ushort);
}
_bufferStream.Write(client._buffer, messageSizeOffset, bytesRead - messageSizeOffset);
if (_bufferStream.Length >= _messageLength)
{
var data = Deserialize(_bufferStream);
//Cleanup
_messageLength = 0;
_bufferStream.Dispose();
_bufferStream = new MemoryStream();
ReceiveCompleted(data);
}
Receive();
}
catch (SocketException ex)
{
ConnectionFailed();
}
}
我只是使用这个简单的序列化和反序列化函数:
private byte[] Serialize(object item)
{
MemoryStream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, item);
return stream.ToArray();
}
public static object Deserialize(MemoryStream stream)
{
var binaryFormatter = new BinaryFormatter();
stream.Seek(0, SeekOrigin.Begin);
return binaryFormatter.Deserialize(stream);
}
有人知道我为什么会收到此错误吗?因为我已经没有头绪了。
我还在以下链接上添加了一个示例:https ://github.com/kevingoos/SocketTest
解决方案
在这里Send
:
public void Send(byte[] data)
{
if (ClientSocket != null && ClientSocket.Connected)
{
ClientSocket.BeginSend(AddSize(data), 0, data.Length, 0, ResponseSend, this);
}
else
{
ConnectionFailed();
}
}
您发送data.Length
字节,但这些AddSize()
方法ushort
在缓冲区的开头添加了一个消息长度字段。该字段的大小必须包含在发送的内容中。
推荐阅读
- composer-php - 如何使依赖项使用其依赖项的修补版本?
- c++ - c ++同步队列/线程应用程序在启动时崩溃,没有特定原因
- python - 在 jupyter 笔记本中翻译 matplotlib 绘图轴标签
- arrays - 从另一个对象内部的对象中过滤数据
- javascript - 在 Cloud Functions 中写入 Firestore 时如何使用 SetOptions.merge 和 .set()
- salesforce - Salesforce 公式
- sql-server - 痛苦的缓慢查询,我有什么选择?
- c# - C# How to Pass Anon Class by Reference
- c# - 树莓派上的 Azure 语音 SDK
- laravel - 在子文件夹中部署 Laravel 5.8 - 路由无法正常工作