Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# memorystream复制到网络流问题_C#_Networking_Memorystream_Networkstream_Binaryformatter - Fatal编程技术网

C# memorystream复制到网络流问题

C# memorystream复制到网络流问题,c#,networking,memorystream,networkstream,binaryformatter,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,

我这里的代码有问题

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


本质上,我想做的是将该类序列化到网络流,并在其前面设置序列化数据的大小。如果有人有更好的方法让我知道

在调用CopyTo(使用ms.Seek(0,SeekOrigin.Start))之前,可能需要将内存流倒回到开始处。

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

试用

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

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

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

在本例中,您将“长度”写入流的开头

以下方面应起作用:

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

我的猜测是,在您离开using块之后,NetworkStream将被释放,因为它超出了范围。您可以尝试在使用块结束之前刷新它。或者您的问题出在其他地方了?在使用结束之前尝试刷新memorystream和networkstream,但似乎也没有效果。您需要另一个
ms.Position=0
ms.之后写入
。编辑:实际上第一个
ms.Position=0似乎是错误的,因为您正在覆盖刚刚编写的数据。@leppie-Omg,别傻了。我只是想它会将那里的数据向前移动(出于某种原因),但是,你是对的,它只是覆盖了已经写入的内容。这一定是问题所在。@kelton52:我会添加答案,以防万一:)我发现有两件事不对,ns无法解决最后一个块。另外,我不想关闭网络流。我将对其进行修改,并对其进行一次尝试。在外部使用ns进行更新,但没有关闭。没关系,我可能没有提供足够的详细信息或其他信息。我希望消息大小位于流的开头,这是否可行?这似乎会把它抛在数据后面。对不起,再次缺乏细节。这基本上就是我开始使用的代码,但我想重写它,这样我就不必有任何超出messsize的数组。我正在尝试快速完成这项工作,每次数据都超过1mb(用于lan连接)。我希望能够以一种不必将流放入数组的方式操作流,这是最昂贵的调用。@kelton52:使用2个MemoryStream可能是最好的选择,或者,不要使用
stream.CopyTo
。我会(再次)更新答案。是的,更新2是我刚想到的,但为什么你说不要使用Stream.CopyTo?@kelton52:因为缺乏明确的文档。有关设置位置的信息,请参见注释。毕竟,在它下面只做
Stream.Read
Stream.Write