2

C#でネットワークストリームを使用してTCP経由でカスタムオブジェクトをシリアル化するときに、 Stream notWritableExceptionの考えられる原因は何ですか。Mp3データをパケットの形式で送信しています。フレームはByte[]バッファで構成されています。オブジェクトをシリアル化するためにBinaryFormatterを使用しています。

BinaryFormatter.Serialize(NetworkStream、Packet);

歪みとジッターのあるクライアントで再生されたMp3が数秒間終了した後、上記の例外が発生しました。NAudioオープンソースライブラリを使用しています。

この変更を行う前に、私は使用していました

NetworkStream.Write(Byte [] Buffer、0、EncodedSizeofMp3); そしてそれは例外を与える前にそれをうまく書いていました

4

1 に答える 1

3

に書き込んでいる場合はNetworkStream、ストリーム/ソケットが閉じている可能性があります

に書き込んでいる場合はNetworkStream、で作成されている可能性がありますFileAccess.Read

ただし、推測しなければならない場合は、何かがストリームを閉じているように聞こえます。たとえば、ルート上の「ライター」がストリームを所有していると想定しているため、ストリームを途中で閉じている場合があります。リクエストStreamを無視するある種のラッパーを作成して使用する必要があるのはかなり一般的です(実際、TCPコードを作成しているので、現在、目の前にラッパーがあります)。Close()

さておき、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;
    }
}
于 2012-02-03T16:00:27.167 に答える