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

Подробности о приложении:

  • Разработано в Visual Studio 2019 (Windows 10)
  • Разработано на платформе UWP с использованием C# и языка XAML.

Приложение получает информацию с удаленного сервера. Соединение через Socket используется для связи между двумя сторонами.

Сервер отправил кадром сообщение, и в этом сообщении мы находим несколько основных элементов, каждый из которых имеет размер и другое определение, как показано ниже:

Содержание каждого сообщения:

- Name: ID Message / Type : UINT16 / Size : 4 bytes
- Name: ID Device/ Type : UINT8 / Size : 4 bytes
- Name: Temperature / Type : UINT16 / Size : 4 bytes
- Name: Activation / Type : BOOLEAN / Size : 4 bytes
- Name: Weather / Type : STRING[32] / Size : 16 bytes

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

Вот мой код, который поэтому находится в фоновой задаче:

StreamReader reader;
int SizeBuffer = 2048;
int SizeReceive = 0;

reader = new StreamReader(socket.InputStream.AsStreamForRead());
string result;

result = "";
while (true)
{
    char[] buffer = new char[SizeBuffer];
    SizeReceive = await reader.ReadAsync(buffer, 0, SizeBuffer);

    int i = 0;

    Debug.WriteLine("Text 1 : ")
    while (i < 2047)
    {
        Debug.WriteLine(buffer[i]);
        i++;
    }

    string data = new string(buffer);

    if (data.IndexOf("\0") >= 0 || reader.EndOfStream)
    {
        result = data.Substring(0, data.IndexOf("\0"));
        break;
    }
    result += data;
}

Debug.WriteLine("Text 2 : " + result);
dataString = result;

Я использую два Debug.WriteLine для просмотра входящих данных.

Вот в чем проблема. Для сообщения Text1 я получаю такой символ: ������������������������

А для сообщения Text2 я получаю один символ:

Как я могу полностью получить свое сообщение и сохранить его в каждом из перечисленных выше параметров в зависимости от его типа и соответствующего размера?

Вместо того, чтобы читать char из потока, как насчет чтения необработанных байтов, поскольку char представляет собой 2-байтовый символ UTF-16. Вероятно, вы видите искаженный вывод из-за предположения о кодировке символов.

phuzi 22.05.2019 11:52

Как STRING[32] вписывается в Size : 16 bytes ? Что является STRING[32] ?

Henk Holterman 22.05.2019 12:01

@phuzi Я не нашел метода, который работает для прямого чтения байтов ... Если у вас есть пример, это мне очень помогло бы

Valentin Dubois-Pivot 22.05.2019 14:08

@HenkHolterman Не знаю... Так написано в документации сервера... Это действительно странно

Valentin Dubois-Pivot 22.05.2019 14:08

Вы вообще знаете, что в сообщении содержится байт Как много?

Henk Holterman 22.05.2019 14:55

@henkholterman Нет, это может зависеть от сообщения, в котором проблема. Я бы смог показать хотя бы начало, что бы потом было легче

Valentin Dubois-Pivot 22.05.2019 15:03

Часть «Содержание каждого сообщения:» предлагает фиксированный размер.

Henk Holterman 22.05.2019 15:08

@henkholterman Да, каждый параметр имеет фиксированный размер. С другой стороны, сообщение, отправленное с сервера, должно обязательно содержать идентификатор сообщения и идентификатор устройства, но не обязательно индикацию погоды на каждом из них.

Valentin Dubois-Pivot 22.05.2019 15:12

Это не имеет смысла. Если я не укажу температуру, как он узнает, что отсутствует «активация»?

Henk Holterman 22.05.2019 15:21

@HenkHolterman Да, я знаю, это звучит странно, но в отношении нашего идентификатора сообщения мы можем знать, какими будут параметры впоследствии. Я плохо объяснил. Мне удалось восстановить данные в шестнадцатеричном формате с помощью нового метода.

Valentin Dubois-Pivot 22.05.2019 16:29
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
1
11
96
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Конструктор StreamReader по умолчанию с одним аргументом использует кодировку UTF-8. Возможно, ваш сервер отправляет данные в другой кодировке.

Попробуйте явно указать кодировку с помощью StreamReader(stream, encoding) конструктор.

Ответ принят как подходящий

Вот решение:

try
{
    DataReader reader1 = new DataReader(socket.InputStream);
    reader1.InputStreamOptions = InputStreamOptions.Partial;
    uint numFileBytes = await reader1.LoadAsync(2048);
    byte[] byArray = new byte[numFileBytes];
    reader1.ReadBytes(byArray);
    string test = BitConverter.ToString(byArray);

    Debug.WriteLine("Conversion : " + test);
}
catch (Exception exception)
{
    Debug.WriteLine("ERROR LECTURE : " + exception.Message);
}

Почему вы думаете, что это решение?

Uwe Keim 23.05.2019 09:41

@UweKeim Я протестировал решение в своем проекте, и оно отлично работает. Я получаю шестнадцатеричное число, а затем конвертирую его для использования.

Valentin Dubois-Pivot 23.05.2019 09:45

Другие вопросы по теме