• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Решено Парсинг ответа с сайта

ave

New member
Подскажите, как правильно написать эту функцию, чтобы она принимала ответ в строку и раздиляла эту строку на три строки по "/".
Формат ответа с сайта:
PHP:
<? echo "1/20.2/25.4\r"; ?>
Ошибка на команде pch = strtok(line,"/");
Не знаю как формат переменных String и char согласовать.
Код:
while (client.available()) {
    //char line = client.read();
    String line = client.readStringUntil('\r');
    char *pch;
    Serial.print("Reply: ");
    Serial.println(line);
    pch = strtok(line,"/");
    while (pch != NULL) {
      Serial.println(pch);
      pch = strtok(NULL,"/");
    }
    //if (line == '1') digitalWrite(led,1); else digitalWrite(led,0);
}
 

Юрий Ботов

Moderator
Команда форума
как то так:
String S = "123";
char buf[30];
S.toCharArray(buf, 30);
а этот buf уже отдаешь в strtok(buf,"/\"")
 

lsm

Разработчик Smart.js
Команда форума
Если точно известно что компоненты всего три, то:

Код:
char a[20], b[20], c[20];


if (sscanf(line.c_str(), "%19[^/]/%19[^/]/%19s", a, b, c) == 3) {
   // success
} else {
   // error
}
 

ave

New member
lsm, да, у меня всегда три компоненты.
Но у мены возникает ошибка, такая же как здесь:
Вопрос - sscanf
И ее решение мне не понятно.
 

ave

New member
https://zxlogin.com/zxloginteplo.php?com=n&newt1=19.94&newt2=19.87&s=1&id=10650774
По этой посылке от модуля данные в базу записываются и хостинг выдает ответ "1/30/20", но у меня почему-то в середину while вызов не попадает. "Ok" не выводится. В чем может быть причина? Как работает client.available()?
Код:
client.print(String("GET ")+url+" HTTP/1.1\r\nHost: "+host_zxlogin+"\r\nConnection: close\r\n\r\n");
client.flush();     // ждем отправки всех данных

while (client.available()) {
  Serial.println("Ok");
}
 
Последнее редактирование:

pvvx

Активный участник сообщества
Как работает client.available()?
Вроде говорит, есть ли у клиета принятые данные.
Что-то по вашему адресу мусор с "1/30/20"
Код:
#include <WiFi.h>
#include <myAP.h>

#ifndef _MYAPCFG_H_
char ssid[] = "yourNetwork"; //  your network SSID (name)
char pass[] = "password";    // your network password (use for WPA, or use as key for WEP)
#endif //_MYAPCFG_H_

char server[] = "zxlogin.com";    // name address for Google (using DNS)

WiFiSSLClient client;
/* if ssl_handshake returned -0x7200 ->
SSL_MAX_CONTENT_LEN to sufficient size (maximum value is 16384).
default value 4096. */
extern "C" unsigned int mfl_code_to_length[]; // mfl_code_to_length[0] = SSL_MAX_CONTENT_LEN

void setup() {
  mfl_code_to_length[0] = 16384; // = max SSL_MAX_CONTENT_LEN
  // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
  WiFi.begin(ssid,pass);
}

void loop() {
  printf("\r\n");
  if (client.connect(server, 443)) {
    // Make a HTTP request:
    char * buf = new char [512];
    sprintf(buf, "GET /zxloginteplo.php?com=n&newt1=19.94&newt2=19.87&s=1&id=10650774 HTTP/1.1\r\n\Host: %s\r\n\Connection: close\r\n", server);
    client.println(buf);
    delete [] buf;
    while (client.connected()) {
      // if there are incoming bytes available
      // from the server, read them and print them:
      while (client.available()
             // пропуск HTTP заголовка
             && client.read() == 13 && client.read() == 10
             && client.read() == 13 && client.read() == 10) {
        while (client.available()) Serial.write((unsigned char)client.read());
        delay(50);
        printf("disconnecting...");
        client.stop();
        sys_info();
        delay(60000);
        return;
      }
    }
  }
  delay(10000);
}
Код:
Initializing WIFI ...
WIFI initialized
Interface 0 IP address : 192.168.1.122
b
п»ї1/30/20
0

disconnecting...
CLK CPU         166666666 Hz
RAM heap        74216 bytes
TCM heap        27928 bytes

b
п»ї1/30/20
0

disconnecting...
CLK CPU         166666666 Hz
RAM heap        74224 bytes
TCM heap        27928 bytes

b
п»ї1/30/20
0

disconnecting...
CLK CPU         166666666 Hz
RAM heap        74224 bytes
TCM heap        27928 bytes
 
Последнее редактирование:

pvvx

Активный участник сообщества
Ещё ваш сервер выдает данные в Transfer-Encoding: chunked... Ему бир-бар, даже если указать HTTP/1.0.
А эксплореру - сжатым в gzip. Но эксплорер в заголовке запроса разрешает gzip...
HTTP/0.9 и HTTP/2 он ответил:
Код:
HTTP/1.1 400 Bad Request
Server: nginx
Date: Tue, 22 Nov 2016 06:09:32 GMT
Content-Type: text/html
Content-Length: 166
Connection: close

<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
Дурной сервер: Transfer-Encoding: chunked: Он стал доступен только начиная с HTTP версии 1.1 (HTTP/1.1).
Ответ его без "HTTP/x" GET URI — для версии протокола 0.9;
Код:
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
:)
 
Последнее редактирование:

ave

New member
Как работает сжатие GZIP
По вашим наводкам нахожу полезные статьи и узнаю все больше интересного и нового для себя.
Но, пока не понимаю куда копать чтобы решить проблему.

1. В ответе в конце строки убрал \r.
PHP:
<? echo "1/20/30"; ?>
2. Перекодировал страницу с UTF-8 в ANSI (в ответе нет русских букв и трафик будет меньше, я так думаю).
3. Заменил протокол GET посылки на HTTP/0.9.

И еще есть непонятные моменты.

client.flush() - Здесь ждем отправки всех данных, здесь понятно.
while (client.available()) - А здесь не понятно.

До прихода ответа, я так понимаю client.available() = 0.
Но програма подождала отправки и не дожидаясь ответа идет дальше минуя while (0).
Я думаю тут что-то не то.
 
Последнее редактирование:

ave

New member
ClientAvailable Программирование Ардуино

Я так понял функция while (client.available()) должна быть в основном цикле loop(), а то она у меня была в функции sendServer_zxlogin() из которой программа успешно выходила и не могла там принять ответ. client.stop() убрал из sendServer_zxlogin(), но все равно ответ не приходит. ((
Код:
void loop (void) {
  server.handleClient();
  delay(1);
  while (client.available()) {
    Serial.println("Ok");
    client.stop();
  }
}
 
Последнее редактирование:

ave

New member
Заработало! Наконец то ответ получил.
Закомментировал client.flush(). Почему ответ приходит только после отключения client.flush()...

ClientFlush Программирование Ардуино
StreamFlush Программирование Ардуино


Код:
void sendServer_zxlogin(int state) {
  if (!client.connect(host_zxlogin,httpsPort)) {
    Serial.print(host_zxlogin);
    Serial.println(" - Connection failed.");
    client.stop();
    return;
  }

  String url = "/zxloginteplo.php?com=n&newt1="+(String)ft1+"&newt2="+(String)ft2+"&s="+(String)ledStatus+"&id="+(String)chipId;

  Serial.print("Sending URL: ");
  Serial.print(host_zxlogin);
  Serial.println(url);

  client.print(String("GET ")+url+" HTTP/1.1\r\nHost: "+host_zxlogin+"\r\nConnection: close\r\n\r\n");
  //client.flush();     // ждем отправки всех данных
}

void loop (void) {
  server.handleClient();
  delay(1);

  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
}
В терминале:
Код:
Sending URL: zxlogin.com/zxloginteplo.php?com=n&newt1=19.62&newt2=19.62&s=0&id=10650774
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 22 Nov 2016 19:54:20 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: close

7
1/30/20
0
 
Последнее редактирование:

ave

New member
Парсинг ответа сервера с фиксированным количеством параметров "{1/30/20}".
Добавил "{}" для упрощения выделения строки.
Код:
while (client.available() && client.read() == '{') {
    int a,b,c;
    char *pch;
    char buf[30];
    String var;
    String line = client.readStringUntil('}');
    line.toCharArray(buf,30);
    pch = strtok(buf,"/");
    var = (String)pch;
    a = var.toInt();
    pch = strtok(NULL,"/");
    var = (String)pch;
    b = var.toInt();
    pch = strtok(NULL,"/");
    var = (String)pch;
    c = var.toInt();
    Serial.println(a);
    Serial.println(b);
    Serial.println(c);
    client.flush();
    client.stop();
    return;
}
В терминале:
Код:
Sending URL: zxlogin.com/zxloginteplo.php?com=n&newt1=19.37&newt2=19.31&s=0&id=10650774
1
30
20
 
Последнее редактирование:

achuser

New member
Если точно известно что компоненты всего три, то:

Код:
char a[20], b[20], c[20];


if (sscanf(line.c_str(), "%19[^/]/%19[^/]/%19s", a, b, c) == 3) {
   // success
} else {
   // error
}
вся беда в том, что sscanf на esp не работает, по крайней мере под IDE...

Считать данные, как в примере выше возможно, но тут проблема в том, что только в заданном формате, например sscanf мог работать со строкой любого размера и кол-ва переменных. А здесь если задано 3, то одну или 4 не передашь, будет кидать мусор в сериал...

Никто аналог sscanf не придумал еще под есп? :)
 
Последнее редактирование:

achuser

New member
Гляну на досуге, пока решил немного иным путем пойти,чтобы меньше со строкой работать, но ежели аналогичная функция будет, можно и вернуться к ней :)

Пока проблема нарисовалась другая, nodeMCU зависает минут через 25 работы, ардуина у меня работала неделями )
 
Сверху Снизу