Каковы возможные причины для исключения потока без записи? - PullRequest
2 голосов
/ 03 февраля 2012

Каковы возможные причины Поток исключен для записи при сериализации пользовательского объекта через TCP с использованием сетевого потока в C #.Я отправляю данные Mp3 в виде пакетов. Кадр состоит из буфера Byte []. Я использую двоичный форматер для сериализации объекта.

BinaryFormatter.Serialize (NetworkStream, Packet);

Воспроизведение Mp3 на клиенте с искажением и дрожанием заканчивается на несколько секунд, а затем возникает указанное выше исключение. Я использую для этого библиотеку с открытым исходным кодом NAudio.

Перед выполнением этой модификации я использовал

NetworkStream.Write (Byte [] Buffer, 0, EncodedSizeofMp3); и он успешно записывал его, прежде чем выдать какое-либо исключение

1 Ответ

3 голосов
/ 03 февраля 2012

Если вы пишете в 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;
    }
}
...