4

Я использую сетевой протокол, построенный вокруг TcpClient, используя BinaryReader прочитать байты из базового NetworkStream (и, наоборот, с помощью BinaryWriter писать).Count байт, переданных через TcpClient NetworkStream BinaryReader/BinaryWriter

Протокол передает строки в кодировке UTF-8 и вызывает reader.ReadString(), чтобы прочитать их из потока (используя writer.Write(someStr) для записи).

Есть ли простой способ определить количество байтов, считанных (или записанных) в NetworkStream, без необходимости перескакивать через обручи, чтобы вычислить фактические длины байтов переданных строк?

Обратите внимание, что BinaryWriter.Write() записывает целое число в 7 бит до фактических байтов строки, что делает любой ручной расчет дополнительно сложным.

Также обратите внимание, что NetworkStream не поддерживает собственность Position, так как она жалуется на то, что не сможет Seek.

Кроме того, я хотел бы избежать введения посредников, которые должны копировать/сканировать данные в процесс чтения/записи, чтобы не влиять на производительность всей системы.

Есть ли простой, способ высокого уровня подсчета байтов, проходящий через сетевой интерфейс, без необходимости вручную учитывать кодировку и длину строк?

+0

Что вы хотите достичь? Вы можете вставить настраиваемый поток между сетевым потоком и считывателем, который подсчитывает байты. – usr

+0

@usr Мне просто нужно знать, сколько байт прочитано/написано - для целей отчетности. * Что-то * в стеке базового протокола должно знать количество отправленных/полученных байтов ... Я хотел бы получить эту информацию - с минимальными хлопотами. – Optimax

ответ

1

Вы можете вставить настраиваемый поток между сетевым потоком и считывателем, который подсчитывает байты.

Нет необходимости копировать данные для этого. Просто добавьте количество байтов, которое будет передано счетчику.

+0

Вы могли бы набросать пример того, как это сделать? – Optimax

+0

Любые конкретные проблемы? Выведите из потока и оберните другой экземпляр потока таким образом. – usr

+0

Не нужно ли включать буферизацию данных? Я не хочу замедлять ход событий. – Optimax

0

Для тех, кто интересуется, как я реализовал поток байт-счета, здесь во всей своей красе (или подлости, в зависимости от обстоятельств может быть):

using System; 
using System.IO; 

namespace Streams 
{ 
    /// <summary> 
    /// A wrapper around a <see cref="Stream"/> that keeps track of the number of bytes read and written. 
    /// </summary> 
    public class ByteCountingStream : Stream 
    { 
     private readonly Stream inner; 

     private long totalBytesWritten; 
     private long totalBytesRead; 


     public ByteCountingStream(Stream inner) 
     { 
      this.inner = inner; 
     } 

     public override void Flush() 
     { 
      inner.Flush(); 
     } 

     public override long Seek(long offset, SeekOrigin origin) 
     { 
      throw new NotImplementedException(); 
     } 

     public override void SetLength(long value) 
     { 
      throw new NotImplementedException(); 
     } 

     public override int Read(byte[] buffer, int offset, int count) 
     { 
      int readBytes = inner.Read(buffer, offset, count); 
      totalBytesRead += readBytes; 
      return readBytes; 
     } 

     public override void Write(byte[] buffer, int offset, int count) 
     { 
      inner.Write(buffer, offset, count); 
      totalBytesWritten += count; 
     } 

     public override bool CanRead => true; 
     public override bool CanSeek => false; 
     public override bool CanWrite => true; 

     public override long Length 
     { 
      get 
      { 
       throw new NotImplementedException(); 
      } 
     } 

     public override long Position { get; set; } 

     public long TotalBytesWritten => totalBytesWritten; 
     public long TotalBytesRead => totalBytesRead; 
    } 
} 

Реализация проходит буфер к базовому потоку, так что, действительно, нет никакого копирования данных.

+1

'Length' выглядит сломанным. Это не всегда возвращает 0? Должен бросить. – usr

+0

@usr Вправо. Исправлена. – Optimax

+0

Позиция тоже.Я почти забыл об этом с новым синтаксисом tutorial 6.0. Нужно привыкнуть к этому. Кроме того, я думаю, что без утилизации этот класс опасен. – usr

 Смежные вопросы

  • Нет связанных вопросов^_^