2012-02-03 128 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

相關問題