У меня есть байтовый массив, который я читаю из NetworkStream. Первые два байта сообщают длину следующего пакета, а затем пакет считывается в байтовый массив этой длины. Данные, которые мне нужно прочитать из массива NetworkStream / byte, содержат несколько строк, то есть данные переменной длины, оканчивающиеся символами новой строки, и некоторые поля фиксированной ширины, такие как байты и длинные. Итак, как-то так:
// I would have delimited these for clarity but I didn't want
// to imply that the stream was delimited because it's not.
StringbyteStringStringbytebytebytelonglongbytelonglong
Я знаю (и могу сказать, что) формат встречающегося пакета данных, и мне нужно прочитать «строку» для каждого строкового значения, но прочитать фиксированное число байтов для байтов и долго. До сих пор мое предлагаемое решение состояло в том, чтобы использовать цикл while
для чтения байтов во временном байтовом массиве до появления символа новой строки. Затем преобразуйте байты в строку. Мне это кажется клёвым, но я не вижу другого очевидного пути. Я понимаю, что могу использовать StreamReader.ReadLine()
, но это будет связано с другим потоком, и у меня уже есть NetworkStream
. Но если это будет лучшим решением, я попробую.
Другой вариант, который я рассмотрел, заключается в том, чтобы моя бэкэнд-команда записала один или два байта для длин этих значений String, чтобы я мог прочитать длину и затем прочитать String на основе указанной длины.
Итак, как вы можете видеть, у меня есть несколько вариантов, как это сделать, и я хотел бы услышать ваше мнение о том, что вы считаете лучшим способом сделать это. Вот код, который я сейчас имею для чтения всего пакета в виде строки. Следующим шагом является выделение различных полей пакета и выполнение фактической работы по программированию, которая должна быть выполнена, создание объектов, обновление пользовательского интерфейса и т. Д. На основе данных в пакете.
string line = null;
while (stream.DataAvailable)
{
//Get the packet length;
UInt16 packetLength = 0;
header = new byte[2];
stream.Read(header, 0, 2);
// Need to reverse the header array for BitConverter class if architecture is little endian.
if (BitConverter.IsLittleEndian)
Array.Reverse(header);
packetLength = BitConverter.ToUInt16(header,0);
buffer = new byte[packetLength];
stream.Read(buffer, 0, BitConverter.ToUInt16(header, 0));
line = System.Text.ASCIIEncoding.ASCII.GetString(buffer);
Console.WriteLine(line);
}