【问题标题】:Failed to read past end of stream无法读取流的结尾
【发布时间】:2016-05-31 08:47:10
【问题描述】:

所以我尝试在 Unity 5.3 中使用 UDP 通过网络发送一些数据。因为包裹可能太大而无法一次发送,所以我尝试将它们分成较小的包裹。 (注意:这些包​​每秒发送 30 次,因此丢失某个包真的无关紧要)

我基本上做的是:

  1. 创建字节数组
  2. 拆分成不同的、更小的字节数组
  3. 将字节数组与其他信息一起添加到序列化类中
  4. 将序列化类转换为字节数组
  5. 在接收客户端上发送,反之亦然

当我尝试反序列化接收到的字节数组时收到错误“无法读取流结束”。

这是反序列化的代码:

private static object ToObject(byte[] data)
{
    var formatter = new BinaryFormatter();
    using (var stream = new MemoryStream(data))
    {
        stream.Seek(0, SeekOrigin.Begin);
        return formatter.Deserialize(stream);    // exception thrown here  
    }
}

序列化:

private static byte[] ToByteArray(object source)
{
    var formatter = new BinaryFormatter();
    using (var stream = new MemoryStream())
    {
        formatter.Serialize(stream, source);                
        return stream.ToArray();
    }
}

类:

[System.Serializable]
public class Chunk
{
    public short ID {get; set;}
    public short ChunkAmount {get; set;}
    public System.Int64 FrameID {get; set;}
    public byte[] ChunkData {get; set;}
}

知道什么会导致这个异常吗?

你可以通过解决这个问题为我节省一顶假发。所以提前谢谢!

编辑:

提供的处理序列化的函数:

public static List<byte[]> GetChunks(List<byte> bytes, int maxChunkSize, System.Int64 frameID)
{
    var list = new List<byte[]>(); 

    for (int i=0; i < bytes.Count; i+= maxChunkSize) 
    { 
        list.Add(bytes.GetRange(i, Mathf.Min(maxChunkSize, bytes.Count - i)).ToArray()); 
    } 

    List<byte[]> serializedChunks = new List<byte[]>();
    for(int i = 0; i < list.Count; i++)
    {
        Chunk c = new Chunk();
        c.ID = (short)i;
        c.ChunkData = list[i].ToArray();
        c.ChunkAmount = (short)list.Count;
        c.FrameID = frameID;

        serializedChunks.Add(ToByteArray(c));
    }

    return serializedChunks;
}

//Deserialized a chunk from byte array
public static Chunk AssembleSingleChunk(byte[] serializedChunk)
{
    return (Chunk)ToObject(serializedChunk);
}

public static byte[] AssembleChunks(List<Chunk> chunks)
{
    List<Chunk> chunkList = new List<Chunk>(chunks);
    List<Chunk> sortedChunkList = chunkList.OrderBy(c => c.ID).ToList();

    List<byte> allBytes = new List<byte>();
    for (int i = 0; i < sortedChunkList.Count; i++)
    {
        allBytes.AddRange(sortedChunkList[i].ChunkData);
    }

    return allBytes.ToArray();
}

【问题讨论】:

  • 如果dataToObject 与发送的字节完全相同,则不会出现此错误。但是您提供的代码很难猜出错误...
  • 我明白了,但它总是让我对每个收到的包裹都感到异常。我用组装序列化类的代码更新问题

标签: c# serialization unity3d memorystream binaryformatter


【解决方案1】:

找到了……

与上面的代码没有任何关系,而是与接收客户端的缓冲区有关。我将缓冲区设置为 1024 字节,而发送的包超过了该大小。

因此,有两种解决方法:

  1. 增加缓冲区大小
  2. 读取缓冲区、存储数据、清除缓冲区、读取数据、添加数据等。(未测试,只是假设)

随时向我们提供更多知识!

【讨论】:

    猜你喜欢
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多