memorystream copyto网络流问题

时间:2011-11-29 08:38:23

标签: c# networking memorystream networkstream binaryformatter

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

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)似乎不起作用?

基本上我想要做的是将类序列化为网络流,其前面是序列化数据的大小。如果有人有更好的方法,请告诉我!

3 个答案:

答案 0 :(得分:2)

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

在您的情况下,您将'length'写入流的开头。

以下内容应该有效:

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);
}

<强>更新

要将'length'写入开头,请使用临时流/字节[]。

示例:

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); 
}

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

尝试使用

Stream.Flush()
Stream.Close()

在完成任何Stream之前。

还用这样的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();
    }
}

在此之后你应该能找到你的问题。