EndianBinaryReader - Сомнительное обновление входного потока? - PullRequest
2 голосов
/ 22 января 2010

Я пытаюсь использовать EndianBinaryReader и EndianBinaryWriter, которые Джон Скит написал как часть своего misc utils lib . Он отлично работает для двух использований, которые я использовал.

Первое чтение из сетевого потока (TCPClient), где я сижу в цикле, читая данные по мере их поступления. Я могу создать один EndianBinaryReader, а затем просто избавиться от него при завершении работы приложения , Я строю EndianBinaryReader, передавая TCPClient.GetStream in.

Сейчас я пытаюсь сделать то же самое при чтении из UdpClient, но у него нет потока, поскольку он меньше соединения. поэтому я получаю данные, как это

byte[] data = udpClientSnapShot.Receive(ref endpoint);

Я мог бы поместить эти данные в поток памяти

var memoryStream = new MemoryStream(data);

, а затем создайте EndianBinaryReader

var endianbinaryReader = new EndianBinaryReader(
    new BigEndianBitConverter(), memoryStream,Encoding.ASCII);

но это означает, что мне нужно создавать новый читатель с порядком байтов каждый раз, когда я читаю. Есть ли способ, где я могу просто создать отдельный поток, который я могу просто продолжать обновлять inputsream данными с клиента udp?

Ответы [ 2 ]

1 голос
/ 22 января 2010

Лучшим вариантом, вероятно, является переопределение класса .NET Stream для предоставления пользовательских функций. Класс предназначен для переопределения с пользовательским поведением.

Это может показаться пугающим из-за количества членов, но это проще, чем кажется. Существует ряд логических свойств, таких как «CanWrite» и т. Д. Переопределите их и сделайте так, чтобы все они возвращали «false», за исключением функций, которые нужны вашему читателю (вероятно, CanRead - единственное, что вам нужно, чтобы быть истинным).

Затем просто переопределите все методы, которые начинаются с фразы «При переопределении в производном классе» в справке по Stream , а неподдерживаемые методы возвращают «UnsupportedException» (вместо значения по умолчанию). "NotImplementedException".

Реализуйте метод Read, чтобы возвращать данные из ваших буферизованных пакетов UDP, используя, возможно, связанный список буферов, устанавливая использованные буферы на «ноль», когда вы читаете мимо них, чтобы объем памяти не рос неограниченно.

1 голос
/ 22 января 2010

Не могу вспомнить, буферизует ли EndianBinaryReader - можно ли перезаписать один MemoryStream? Но, честно говоря, от лишнего объекта здесь очень мало накладных расходов. Насколько большие пакеты? (вставка в MemoryStream приведет к клонированию byte[]).

Я бы соблазнился использовать простейшую вещь, которая работает, и посмотреть, есть ли настоящая проблема. Вероятно, единственное изменение, которое я сделает , это ввести using (поскольку они IDisposable):

using(var memoryStream = new MemoryStream(data))
using(var endianbinaryReader = ..blah..) {
    // use it
}
...