【问题标题】:SerializationException when deserializing message send through a socket反序列化通过套接字发送的消息时出现 SerializationException
【发布时间】:2019-10-08 08:22:58
【问题描述】:

我正在创建一个程序,我试图通过套接字系统连接服务器和多个客户端。出于某种原因,当我反序列化时出现异常。

我这样做是为了使第一条消息的 前 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

【问题讨论】:

  • @500-InternalServerError 您使用 data.length 的第一个解决方案就是解决方案,这是我的愚蠢错误。如果您发布此内容,我会将其设置为已解决!

标签: c# .net sockets serialization


【解决方案1】:

这里是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 消息长度字段。该字段的大小必须包含在发送的内容中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 2011-11-26
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多