Дарт, как разобрать байты из строки

1

Приложение на сервере Dart на стороне сервера получает строку JSON из сокета. Строка генерируется кодом Java. Когда строка отправляется в сокет в коде Java, он кодируется в UTF8, а два байта, короткий int, добавляются к строке. Значение этого короткого числа - это количество байтов в строке + 2.

Мне нужно извлечь это значение как int для обработки строки, но ничего, что я пробовал, сработало. Он умирает в JSON.decode (ниже), потому что он встречает начало другой строки JSON. Первый байт второй строки - это начало с длиной второй строки JSON. Две строки имеют длину менее 40 символов.

(Мне нужно будет добавить длину к строкам, отправленным из Dart на Java.)

Строка Java

out.writeUTF(json); // converts and writes to the socket stream.

Метод бокового кода сервера Dart

handleJavaSocket(Socket javasocket){
   javasocket.transform(UTF8.decoder).listen((String socketString){
   var truncated = socketString.substring(2);
   String message = JSON.decode(truncated); // dies here
      // more code
   }, onError: (error) {
     print('Bad JavaSocket request');
   });

}

Одна из строк JSON перед кодированием

{"target":"DOOR","command":"OPEN"}
Теги:
string
dart
sockets

2 ответа

0
Лучший ответ

Я не мог найти способ преобразования двух байтовых заголовков в целое число, особенно потому, что один байт может быть 0, а некоторые строковые методы рассматривают это как ограничитель строк.

Поскольку сообщение из приложения Java всегда будет состоять из заголовка, за которым следует сообщение, я игнорирую заголовок и разбираю сообщения (сообщения) из потока, добавляя их в список (чтобы повторить их как проверку)

Затем я пересекаю список и моделирую заголовок, записывая 0 байт, за которым следует размер сообщения в поток потока, за которым следует сообщение. Это не сработает, так как длина сообщений больше 255, но я не ожидаю, что они будут даже близки к этому размеру.

следует отметить, что приложение Дарт и приложение Java находятся на одной машине.

handleJavaSocket(Socket javasocket){
  // echo socket
  javasocket.transform(UTF8.decoder).forEach((item) {
    var start = 2;
    var end = -1;
    var messages = new List<String>();
    while((++end < item.length) && (end = item.indexOf('}',end)) != -1) {
      messages.add(item.substring(start, ++end));
      start = end + 2;
    }
    for(var message in messages) {
      // header message length as two bytes
      javasocket.writeCharCode(0); // max length 254
      javasocket.writeCharCode(message.length); 
      javasocket.write(message); // <== send
    }
  });

}
2

Итак, вы всегда отправляете как [sizeuper8, sizelower8,..utf8-string...] в качестве границ ваших сообщений? Декодирование UTF8 не ожидает длины в качестве параметра и рассматривает два байта как unicode (возможно, null, за которым следует символ).

В настоящее время я работаю над StreamBuffer for Quiver (https://pub.dartlang.org/packages/quiver), который позволит вам подключить сокет к буферу, который дает вам:

read(2).then((bytes) => read(bytes[1]<<8|bytes[2]).then((string) => UTF8.decode(string)));

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

Текущий запрос на извлечение (выполняется работа): https://github.com/google/quiver-dart/pull/117

  • 0
    Я так и думал, и все работало нормально, когда код Java отправлял строку, а Дарт отправлял ее обратно. Затем я настроил Java-код для отправки второй строки после некоторых вычислений, но оказалось, что вторая строка (или не дай бог - ее часть) была добавлена к первой. И код Java, и код Dart будут находиться на одном компьютере и отправлять строки асинхронно, поэтому я не могу исключить, что эта конкатенация не произойдет в конечном приложении. Я вижу, что Дарт поддерживает UDP ...
  • 0
    Я также использую UDP, и это имело бы смысл для вашего приложения, плюс вы можете отказаться от кодировки длины!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню