Подробности о приложении:
Приложение получает информацию с удаленного сервера. Соединение через 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 я получаю один символ: �
Как я могу полностью получить свое сообщение и сохранить его в каждом из перечисленных выше параметров в зависимости от его типа и соответствующего размера?
Как STRING[32]
вписывается в Size : 16 bytes
? Что является STRING[32] ?
@phuzi Я не нашел метода, который работает для прямого чтения байтов ... Если у вас есть пример, это мне очень помогло бы
@HenkHolterman Не знаю... Так написано в документации сервера... Это действительно странно
Вы вообще знаете, что в сообщении содержится байт Как много?
@henkholterman Нет, это может зависеть от сообщения, в котором проблема. Я бы смог показать хотя бы начало, что бы потом было легче
Часть «Содержание каждого сообщения:» предлагает фиксированный размер.
@henkholterman Да, каждый параметр имеет фиксированный размер. С другой стороны, сообщение, отправленное с сервера, должно обязательно содержать идентификатор сообщения и идентификатор устройства, но не обязательно индикацию погоды на каждом из них.
Это не имеет смысла. Если я не укажу температуру, как он узнает, что отсутствует «активация»?
@HenkHolterman Да, я знаю, это звучит странно, но в отношении нашего идентификатора сообщения мы можем знать, какими будут параметры впоследствии. Я плохо объяснил. Мне удалось восстановить данные в шестнадцатеричном формате с помощью нового метода.
Черный ромб с символом вопросительного знака заменяет нераспознанные символы. Похоже на проблему с кодировкой данных, полученных с сервера.
Конструктор 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);
}
Почему вы думаете, что это решение?
@UweKeim Я протестировал решение в своем проекте, и оно отлично работает. Я получаю шестнадцатеричное число, а затем конвертирую его для использования.
Вместо того, чтобы читать
char
из потока, как насчет чтения необработанных байтов, посколькуchar
представляет собой 2-байтовый символ UTF-16. Вероятно, вы видите искаженный вывод из-за предположения о кодировке символов.