Arduino (c ++), как читать байты из сокетов (WiFiClient)? - PullRequest
0 голосов
/ 09 мая 2020

Сервер в java, отправляет из сокета сервера массив байтов, этот массив байтов содержит текст (utf-8) в следующем формате:

  1. первые 4 байта: int с количество байтов текста
  2. следующие n байтов: каждый байт представляет собой символ.

Итак, я использую «WiFiClient» из библиотеки «ESP8266WiFi.h» (он должен быть таким же, как библиотека "WiFi.h"), WifiClient имеет метод для получения байта с помощью метода read (), проблема в том, что я не могу правильно прочитать int (первые четыре байта) или преобразовать байты в int стоимость. Поэтому я буду очень благодарен, если вы мне поможете с этим:

Java (Сервер) упрощенный код:

String respuestaServer="RESPUESTAS DEL SERVER";
DataOutputStream out=new DataOutputStream(sock.getOutputStream());
out.writeInt(respuestaServer.getBytes(StandardCharsets.UTF_8).length);
out.write(respuestaServer.getBytes(StandardCharsets.UTF_8));
out.flush();

Код Arduino (Клиент) для получения и интерпретации байтового массива ( цель этого кода - преобразовать байты в строку):

String recibirInfo() {
  //TRYING TO READ FIRST FOUR BYTES
  byte bytesSizeMsj[4];
  for (int i = 0; i < sizeof(bytesSizeMsj); i++) {
    bytesSizeMsj[i] = client.read();
    Serial.print("BYTE: "+bytesSizeMsj[i]);
  }
  //TRYING TO TRANSFORM THE FOUR BYTES INTO AN INT
  int sizeMsj = int((unsigned char)(bytesSizeMsj[0]) |
            (unsigned char)(bytesSizeMsj[1]) |
            (unsigned char)(bytesSizeMsj[2])|
            (unsigned char)(bytesSizeMsj[3]));
  Serial.println(sizeMsj);
  char charArray[sizeMsj];
  //TRYING TO READ THE REST OF THE MESSAGE
  for (int i = 0; i < sizeof(charArray); i++) {
    charArray[i] = client.read();
  }
  //TRYING TO TRANSFORM THE BYTE ARRAY INTO A STRING
  String msj=charArray;
  return msj;
}

Ответы [ 2 ]

1 голос
/ 12 мая 2020

Трудно решить такую ​​проблему, вы действительно получаете данные? Можете ли вы показать результат? Может быть, вы даже не подключены.

Также то, что я делал в прошлом, - это преобразование каждого int или «буквы» в char. Поскольку я обычно отправляю сообщение известной длины с начальным символом, я читаю каждый байт своего сообщения и конвертирую его в символ, а затем добавляю его в полученную строку сообщения. Я не знаю, помогает ли это ... Обычно я делаю преобразование по прибытии байта.

0 голосов
/ 14 мая 2020

Я исправил, у меня были проблемы с тем, как я читал из сокета, с тем, как я преобразовываю 4 байта в тип данных Int, и с тем, как я трансформирую байты в String, я выясняю, почему я не получал все байты при попытке чтения из сокета, причина заключалась в том, что когда я вызываю метод client.read (), сервер был недостаточно быстр для отправки информации, поэтому он ничего не читал, поэтому я сделал al oop и с помощью метода client.available () я проверил, есть ли байт, готовый к чтению, поэтому l oop заканчивается, когда были прочитаны первые 4 байта. Затем я преобразовываю считанные 4 байта в Int, читаю остальные байты таким же образом, как раньше, и преобразовываю байты в String.

Вот мой функциональный код:

String recibirInfo(bool* error) {
  String msj = "";
  byte bytesSizeMsj[4];
  for (int i = 0; i < sizeof(bytesSizeMsj); i++) {
    if (client.connected()) {
      if (client.available()) {
        bytesSizeMsj[i] = client.read();
      } else {
        delay(10);
        i--;
      }
    } else {
      *error = true;
      return "";
    }
  }
  //TRANSFORMAR LOS 4 BYTES A INT
  int sizeMsj = 0;
  sizeMsj = ((int)bytesSizeMsj[3]) | sizeMsj;
  sizeMsj = ((int)bytesSizeMsj[2]) << 8 | sizeMsj;
  sizeMsj = ((int)bytesSizeMsj[1]) << 16 | sizeMsj;
  sizeMsj = ((int)bytesSizeMsj[0]) << 24 | sizeMsj;

  char charArray[sizeMsj];
  //LEER EL TEXTO
  for (int i = 0; i < sizeof(charArray); i++) {
    if (client.connected()) {
      if (client.available()) {
        charArray[i] = client.read();
      } else {
        delay(250);
        i--;
      }
    } else {
      *error = true;
      return "";
    }
  }
  //TRANSFORMAR BYTES A STRING
  msj = charArrayToString(charArray, sizeMsj);
  Serial.print("RECIBIDO: ");
  Serial.println(msj);
  return msj;
}

String charArrayToString(char arrChar[], int tam) {
  String s = "";
  for (int i = 0; i < tam; i++) {
    s = s + arrChar[i];
  }
  return s;
}
...