1

我在这里遇到此代码的问题。

using (MemoryStream ms = new MemoryStream())
{
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(ms,SerializableClassOfDoom);
    ms.Position = 0;
    byte[] messsize = BitConverter.GetBytes(ms.Length);
    ms.Write(messsize, 0, messsize.Length);
    NetworkStream ns = Sock.GetStream();
    ms.CopyTo(ns);
    //ms.Close();
}

我无法弄清楚这里发生了什么,或者为什么它不起作用。似乎它没有复制,或者它关闭了网络流,或者其他什么。

对不起,我试过调试它,但如果有人能在这里看到任何明显的问题,我将不胜感激。

顺便说一句,该类可以很好地序列化,并且 MemoryStream 包含数据,但是由于某种原因,执行 ms.CopyTo(ns) 似乎不起作用?

基本上我想要做的是将类序列化为网络流,序列化数据的大小在它之前。如果有人有更好的方法来做到这一点,请告诉我!

4

3 回答 3

2

您在错误的时间重置流位置。

在您的情况下,您将“长度”写入流的开头。

以下应该有效:

using (MemoryStream ms = new MemoryStream())
{
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(ms,SerializableClassOfDoom);
    byte[] messsize = BitConverter.GetBytes(ms.Length);
    ms.Write(messsize, 0, messsize.Length);
    ms.Position = 0;
    NetworkStream ns = Sock.GetStream();
    ms.CopyTo(ns);
}

更新:

要将“长度”写入开头,请使用临时流/字节[]。

例子:

using (MemoryStream ms = new MemoryStream())
{
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(ms,SerializableClassOfDoom);
    byte[] data = ms.ToArray();
    byte[] messsize = BitConverter.GetBytes(ms.Length);
    ms.Position = 0;
    ms.Write(messsize, 0, messsize.Length);
    ms.Write(data, 0, data.Length);
    ms.Position = 0; // again!
    NetworkStream ns = Sock.GetStream();
    ms.CopyTo(ns);
}

更新 2:

更有效的方式。

using (MemoryStream ms = new MemoryStream())
{
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(ms,SerializableClassOfDoom);
    byte[] messsize = BitConverter.GetBytes(ms.Length);
    NetworkStream ns = Sock.GetStream();
    ns.Write(messsize, 0, messsize.Length);
    ms.Position = 0; // not sure if needed, doc for CopyTo unclear
    ms.CopyTo(ns); 
}
于 2011-11-29T09:03:59.340 回答
0

也许您需要在调用 CopyTo 之前将内存流倒回到开头(使用 ms.Seek(0, SeekOrigin.Start))

于 2011-11-29T08:50:09.733 回答
0

我没有看到真正的问题,但我在这里看到了一个小小的重构问题。

尝试使用

Stream.Flush()
Stream.Close()

在完成任何流之前。

也用这样的语句包围它try-catch,以确保即使有异常也会发生关闭和刷新!

Stream s = new Stream();
try{
    s.Write();
}catch(Exception ex){
    //Oh god, we are doomed!
}finally{
    s.Flush();
    s.Close();
}

你的代码看起来像

NetworkStream ns = null;
using (MemoryStream ms = new MemoryStream())
{
    try{
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(ms,SerializableClassOfDoom);
        ms.Position = 0;
        byte[] messsize = BitConverter.GetBytes(ms.Length);
        ms.Write(messsize, 0, messsize.Length);
        ns = Sock.GetStream();
        ms.CopyTo(ns);
        //ms.Close();
    }catch(Exception ex){
        throw;
    }finally{
        ms.Flush();
        if(ns != null)
            ns.Flush();

        ms.Close();
    }
}

在此之后,您应该能够找到您的问题。

于 2011-11-29T08:54:20.200 回答