2012-02-03 131 views
2

在C#中使用网络流过序列化的自定义对象时,TCP哪些流不可写异常的可能原因。 我发送数据包的形式的Mp3。帧由Byte [] Buffer.I使用二进制格式化程序序列化对象。流不可写入异常的可能原因是什么?

BinaryFormatter.Serialize(NetworkStream,Packet);

Mp3在客户端播放失真和抖动结束几秒钟然后上面提到的异常引发。我使用NAudio开源库。

我用

NetworkStream.Write(字节[]缓冲液,0,EncodedSizeofMp3)这样做修改之前; 并成功给予任何异常

回答

3

之前写的,如果你正在写一个NetworkStream,流/插座可如果你正在写一个NetworkStream关闭

,它可能已与FileAccess.Read创建

但是,如果我不得不猜测,听起来好像有什么东西正在关闭流 - 如果沿着路径的“作家”假定它拥有流,那么会过早地关闭流。这是相当普遍的,必须编写和使用某种包装Stream忽略Close()请求(我有一个在我面前,实际上,因为我正在写一些TCP代码)。

作为一个小旁观;我通常建议不要使用BinaryFormatter进行通信(远程处理除外) - 最重要的是:它不是以非常友好的方式“版本”,但在大多数情况下它往往会有点冗长。

下面是我使用目前的包装,在情况下,它可以帮助(在Reset()方法欺骗复位位置,所以调用者可以读取相对位置):

class NonClosingNonSeekableStream : Stream 
{ 
    public NonClosingNonSeekableStream(Stream tail) 
    { 
     if(tail == null) throw new ArgumentNullException("tail"); 
     this.tail = tail; 
    } 

    private long position; 
    private readonly Stream tail; 
    public override bool CanRead 
    { 
     get { return tail.CanRead; } 
    } 
    public override bool CanWrite 
    { 
     get { return tail.CanWrite; } 
    } 
    public override bool CanSeek 
    { 
     get { return false; } 
    } 
    public override bool CanTimeout 
    { 
     get { return false; } 
    } 
    public override long Position 
    { 
     get { return position; } 
     set { throw new NotSupportedException(); } 
    } 
    public override void Flush() 
    { 
     tail.Flush(); 
    } 
    public override void SetLength(long value) 
    { 
     throw new NotSupportedException(); 
    } 
    public override long Seek(long offset, SeekOrigin origin) 
    { 
     throw new NotSupportedException(); 
    } 
    public override long Length 
    { 
     get { throw new NotSupportedException(); } 
    } 
    public override int Read(byte[] buffer, int offset, int count) 
    { 
     int read = tail.Read(buffer, offset, count); 
     if (read > 0) position += read; 
     return read; 
    } 
    public override void Write(byte[] buffer, int offset, int count) 
    { 
     tail.Write(buffer, offset, count); 
     if (count > 0) position += count; 
    } 
    public override int ReadByte() 
    { 
     int result = tail.ReadByte(); 
     if (result >= 0) position++; 
     return result; 
    } 
    public override void WriteByte(byte value) 
    { 
     tail.WriteByte(value); 
     position++; 
    } 
    public void Reset() 
    { 
     position = 0; 
    } 
} 
+0

shoudl在该网络流第二行是文件流? – Chris 2012-02-03 16:10:11

+0

@Chris no; NetworkStream的构造函数接受FileAccess来指示流(最终是否包装Socket)是否用于读/写/两者; [见MSDN](http://msdn.microsoft.com/en-us/library/6z1c325b.aspx) - 或引用:“访问参数设置NetworkStream的CanRead和CanWrite属性。如果指定Write,则NetworkStream允许调用Write方法,如果指定了Read,则NetworkStream允许调用Read方法,如果指定了ReadWrite,则两个方法调用都是允许的。 – 2012-02-03 16:16:16

+0

在做此修改之前,我正在使用 NetworkStream.Write(Byte [] Buffer,0,EncodedSizeofMp3);并且它在给出任何异常之前成功地写入了它 – Samie 2012-02-03 17:05:34

相关问题