#1 2019-10-18 18:09:45

Dessan
Учасник
Зареєстрований: 2019-10-18
Повідомлень: 7

Парсинг Get запроса со стороны сервера Arduino

Добрый день,

На сервер Arduino отправляется get запрос вида:

GET /?username=Dessan&password=12345 HTTP/1.1

Сервер Ардуино принимает запрос и выводит в порт:

GET /?username=Dessan&password=12345 HTTP/1.1
Host: 192.168.0.177:5000
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 YaBrowser/19.9.3.314 Yowser/2.5 Safari/537.36
Origin: null
Accept-Encoding: gzip, deflate
Accept-Language: uk,ru;q=0.9,en;q=0.8

Я хочу, чтоб в результате get запроса я получал отдельно username, отдельно Dessan, отдельно password и отдельно 12345 и мог с этими данными что-то делать, например сравнивать и выполнять какое-либо действие.
Весь get запрос записывается в переменную tempChar но она имеет свой непонятный мне формат и как я не пытался сделать её строковой у меня ничего не вышло. Я создал другую строковую переменную readString и присвоил ей содержимое tempChar. Насколько я понял, строковые переменные в Arduino являются сами по себе массивами. После манипуляций с indexOf и substring мне удалось распарсить нужную мне строку, однако она выводит не полностью слово , к примеру, username а начинает вывод по буквам.
Вот код парсинга строки:

String readString;

...

while (client.connected()) {

      if (client.available()) {

        tempChar = client.read();

        

        //Serial.write(tempChar);

        if (readString.length() < 100 ) {

               readString += tempChar;

               //Serial.print(readString.length());

               ind1 = readString.indexOf("?");

               ind2 = readString.indexOf("=");

               teststring = readString.substring(ind1, ind2);

               teststring.replace("?", " ");

               teststring.trim();

...

Вот результат парсинга (значение в teststring):

u

us

use

user

usern

userna

usernam

username

username

username

username

username

username

username

и далее ещё штук 20 таких вот username

Получается , что если делать проверки содержит ли переменная username , то дальнейший код реагирует и на username и на u и на us и на use и т.д. В принципе оно работает, но хочется иметь нормальный код более менее а не совсем уже говнокод.

Неактивний

#2 2019-10-18 21:58:04

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 384

Re: Парсинг Get запроса со стороны сервера Arduino

Dessan пише:

хочется иметь нормальный код

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

Неактивний

#3 2019-10-18 23:12:41

Dessan
Учасник
Зареєстрований: 2019-10-18
Повідомлень: 7

Re: Парсинг Get запроса со стороны сервера Arduino

А это форум не для обсуждения разве? Я не знал, что тут только предлагают работу нормальным программистам. Хотя для нормального программиста тут вообще нечего делать

Неактивний

#4 2019-10-18 23:37:27

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 384

Re: Парсинг Get запроса со стороны сервера Arduino

Dessan пише:

А это форум не для обсуждения разве?

А чего тут обсуждать? Нет предмета для обсуждения. Тривиальная задача, которую надо просто делать.

Неактивний

#5 2019-10-19 09:31:51

Watchdog
Гість

Re: Парсинг Get запроса со стороны сервера Arduino

Dessan пише:

А это форум не для обсуждения разве? Я не знал, что тут только предлагают работу нормальным программистам. Хотя для нормального программиста тут вообще нечего делать

Это точно, нормальным программистам тут вообще нечего делать! lol Для разбора форматированных строк удобно использовать функцию sscanf(...). А если не хватает места "вышивать крестиками" методами класса String.

#6 2019-10-19 11:47:56

Dessan
Учасник
Зареєстрований: 2019-10-18
Повідомлень: 7

Re: Парсинг Get запроса со стороны сервера Arduino

А эта функция sscanf(...) разве не только для числовых значений формата int? А то у меня числа с буквами вместе стоят

Неактивний

#7 2019-10-19 14:24:06

Watchdog
Гість

Re: Парсинг Get запроса со стороны сервера Arduino

Dessan пише:

А эта функция sscanf(...) разве не только для числовых значений формата int? А то у меня числа с буквами вместе стоят

Не только для числовых. Для всяких. Читайте в руководствах и справочниках по С, как пользоваться.

#8 2019-10-24 09:12:55

AndriyNic
Учасник
Зареєстрований: 2016-06-21
Повідомлень: 8

Re: Парсинг Get запроса со стороны сервера Arduino

Я б на Вашому місці створив дві змінні username та password а тоді б парсив GET запит присвоюючи змінним знайдені результати.
Наприклад:
String answer = client.readStringUntil('\r');                   //Присвоєння зчитаних даних рядковій змінній answer
Далі у Вашому випадку:
if (answer.indexOf("username") != -1){
//Тут код для присвоєння на початку об`явленій змінній String username знайденого значення
}
if (answer.indexOf("password") != -1){
//Тут код для присвоєння на початку об`явленій змінній String password знайденого значення
}

Неактивний

#9 2019-10-30 22:20:56

Avazart
Учасник
Зареєстрований: 2019-05-05
Повідомлень: 181

Re: Парсинг Get запроса со стороны сервера Arduino

Я делаю примерно так:

//------------------------------------------------------------------------------
void serverLoop()
{
  EthernetClient client = server.available();
  client.setTimeout(10000);

  if (client)
  {
    while (client.connected())
    {
      workWithClient(client);
      client.stop();
    }
  }
}
//------------------------------------------------------------------------------
void workWithClient(EthernetClient& client)
{
  // Read headers and get filepath
  String path;
  String content;
  String token;

  HttpMethod method;
  while (client.available())
  {
    const int length = client.readBytesUntil('\n', buffer, bufferSize - 1);
    if (length <= 0)
      break;
    buffer[length] = '\0';
    String line = String((char*)buffer);
    line.trim();

    if (line.startsWith("GET"))
    {
      method = httpGet;
      path = extractFirst(line, "GET", "HTTP");
      path.trim();
    }

    //  Дальнейшая обработка используя extractFirst
    //  ...
   }
}
//------------------------------------------------------------------------------
String extractFirst(const String& text, const String& startWord, const String& endWord)
{
  const int startIndex = text.indexOf(startWord);
  if (startIndex == -1)
    return String();

  int endIndex = text.indexOf(endWord, startIndex);
  if (endIndex == -1)
    return text.substring(startIndex + startWord.length());

  return text.substring(startIndex + startWord.length(), endIndex - startIndex);
}

Остання редакція Avazart (2019-10-30 22:22:19)

Неактивний

#10 2019-11-02 23:39:19

Dessan
Учасник
Зареєстрований: 2019-10-18
Повідомлень: 7

Re: Парсинг Get запроса со стороны сервера Arduino

AndriyNic пише:

Я б на Вашому місці створив дві змінні username та password а тоді б парсив GET запит присвоюючи змінним знайдені результати.
Наприклад:
String answer = client.readStringUntil('\r');                   //Присвоєння зчитаних даних рядковій змінній answer
Далі у Вашому випадку:
if (answer.indexOf("username") != -1){
//Тут код для присвоєння на початку об`явленій змінній String username знайденого значення
}
if (answer.indexOf("password") != -1){
//Тут код для присвоєння на початку об`явленій змінній String password знайденого значення
}

Тут вопрос в том, что все данные могут быть разными. То есть вместо username может быть любой текст, как и вместо password

Неактивний

#11 2019-11-02 23:46:52

Dessan
Учасник
Зареєстрований: 2019-10-18
Повідомлень: 7

Re: Парсинг Get запроса со стороны сервера Arduino

Avazart пише:

Я делаю примерно так:

//------------------------------------------------------------------------------

Как мне объяснил народ, плохая идея забивать сначала всё что приходит в буфер а потом парсить, потому что буфер слишком маленький и если будет много данных, то всё зависнет. Нужно парсить на лету

Неактивний

#12 2019-11-03 00:48:04

Avazart
Учасник
Зареєстрований: 2019-05-05
Повідомлень: 181

Re: Парсинг Get запроса со стороны сервера Arduino

Так размер буфер нужно подбирать.
И именно поэтому стоит использовать Mega вместо UNO.
Если не ошибаюсь  в строке HTTP запроса обычно не более 127 символов (Лучше посмотреть RFС) что должно вполне хватать под буфер для построчного чтения.

Остання редакція Avazart (2019-11-03 00:48:32)

Неактивний

#13 2019-11-03 11:03:18

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 384

Re: Парсинг Get запроса со стороны сервера Arduino

Dessan пише:

Нужно парсить на лету

Таки да.

Неактивний

#14 2019-11-03 11:46:49

Watchdog
Гість

Re: Парсинг Get запроса со стороны сервера Arduino

Dessan пише:

Как мне объяснил народ, плохая идея забивать сначала всё что приходит в буфер а потом парсить, потому что буфер слишком маленький и если будет много данных, то всё зависнет. Нужно парсить на лету

Как пить дать зависнет. Просящий дожен писать так, чтобы можно было обслужить всё последовательно, без откладывания до поступления дополняющих инструкций. Но кто у нас так просить умеет? Всем давай всё с полуслова и сразу! lol А еще исполнитель может не успевать исполнить все желания. Это приводит к необходимости контроля потоков запросов, это типа как официант приностит блюда только после употребления предшествующих, едоком. big_smile Тут всё как в ресторане, только на другом языке. smile

#15 2019-11-03 15:30:50

Avazart
Учасник
Зареєстрований: 2019-05-05
Повідомлень: 181

Re: Парсинг Get запроса со стороны сервера Arduino

А читать по байтику не зависнет? Не несите чушь.
Ведь все равно нужен буфер куда складывать и все равно нужно читать до перевода строки.

Остання редакція Avazart (2019-11-03 15:33:05)

Неактивний

#16 2019-11-03 16:02:25

Watchdog
Гість

Re: Парсинг Get запроса со стороны сервера Arduino

Avazart пише:

А читать по байтику не зависнет? Не несите чушь.
Ведь все равно нужен буфер куда складывать и все равно нужно читать до перевода строки.

Чушь, сейчас, самая востребованная ноша. Её несут все и везде! Складывать пора вёсла, и браться за буфера! lol Их парсить проще, чем поток токенов.

#17 2019-11-03 21:03:35

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 384

Re: Парсинг Get запроса со стороны сервера Arduino

Avazart пише:

все равно нужно читать до перевода строки.

Зачем?

Неактивний

#18 2019-11-03 22:15:43

Avazart
Учасник
Зареєстрований: 2019-05-05
Повідомлень: 181

Re: Парсинг Get запроса со стороны сервера Arduino

ПоТамушта HTTP протокол, есть заголовки(headers) и тело(body). Заголовки идут строками(lines, т.е по разделителю CRLF). Соответственно логично анализировать именно по строкам, по крайней мере пока идут заголовки, тело потом можно читать как надо/угодно, но вообще в данном случае как правило можно тупо отбрасывать, игнорировать так как все интересное у нас содержится в самом URL в параметрах.

Остання редакція Avazart (2019-11-03 22:17:08)

Неактивний

#19 2019-11-04 10:56:45

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 384

Re: Парсинг Get запроса со стороны сервера Arduino

Avazart пише:

логично анализировать именно по строкам

В заголовке http нет ничего, что могло бы, стоя в конце строки, отменить (или как-то повлиять на) то, что стояло в начале. Потому логично анализировать посимвольно, обычным лексическим автоматом. Построчно - это для тех, кто правильно делать не умеет.

Остання редакція Kaka (2019-11-04 10:57:15)

Неактивний

#20 2019-11-04 14:39:47

Avazart
Учасник
Зареєстрований: 2019-05-05
Повідомлень: 181

Re: Парсинг Get запроса со стороны сервера Arduino

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

Неактивний

#21 2019-11-05 01:24:25

Dessan
Учасник
Зареєстрований: 2019-10-18
Повідомлень: 7

Re: Парсинг Get запроса со стороны сервера Arduino

Не форум, а сборище флудеров. Если не знаете как решить задачу, так и не пишите ваши крайне умные мысли ни о чём. Хорошо, что у меня есть рабочее решение через функцию и даже без цикла while (что особенно приятно).

Avazart, за код спасибо, но он не подходит. Более того, длина HTTP запроса зависит от браузера и принимающего сервера и там точно не 127 символов. Через хром можно и 2000+ передать, а вот сколько может обработать сервер arduino за раз я не знаю. Но мне вполне хватит и 500 символов для всех целей.

Моя главная проблема в том, что я не знаю как подключить модули String и stdio в ардуино, в стандартных библиотеках его нет. На западных форумах нашёл, что их качают и устанавливают. Зачем они мне нужны? Хочу понимать как они работают. Вроде что-то скачал, но они не подсвечены совсем в коде красным цветом, как остальные модули и я не знаю так должно быть или нет. К тому же я не понимаю как работают строки, почему вдруг они являются массивами и как из строки сделать цельное слово. Спросить не у кого. На форумах одни юмористы и умники.

Скачал Visual Studio - изучаю строки в С++, а там видно будет.

Неактивний

#22 2019-11-05 02:47:24

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 384

Re: Парсинг Get запроса со стороны сервера Arduino

Dessan пише:

я не знаю как подключить модули String и stdio в ардуино, в стандартных библиотеках его нет.

В студии нет stdio.h ??? А если найду? Пиши #include <stdio.h> и не выпендривайся.

Неактивний

#23 2019-11-05 05:06:01

Dessan
Учасник
Зареєстрований: 2019-10-18
Повідомлень: 7

Re: Парсинг Get запроса со стороны сервера Arduino

Kaka пише:
Dessan пише:

я не знаю как подключить модули String и stdio в ардуино, в стандартных библиотеках его нет.

В студии нет stdio.h ??? А если найду? Пиши #include <stdio.h> и не выпендривайся.

Ок, оно должно подсвечиваться как-то?Почему все модули красным цветом а #include <stdio.h> чёрным?Или это ни на что не влияет?

Неактивний

#24 2019-11-05 07:07:15

Watchdog
Гість

Re: Парсинг Get запроса со стороны сервера Arduino

Dessan пише:

Не форум, а сборище флудеров.  ... я не понимаю как работают строки, почему вдруг они являются массивами и как из строки сделать цельное слово. Спросить не у кого. На форумах одни юмористы и умники.
Скачал Visual Studio - изучаю строки в С++, а там видно будет.

Про флудеров и юмористов это точно. Вы хоть один учебник прочитали? Например этот: https://proklondike.net/books/cpp/cplus_dlja_chainikov.html Строка в С/С++ это и есть массив символов, только всегда завершающийся терминальным символом равным нулю. А класс String это слишком долгий разговор для форума.

#25 2019-11-05 12:47:15

Avazart
Учасник
Зареєстрований: 2019-05-05
Повідомлень: 181

Re: Парсинг Get запроса со стороны сервера Arduino

Avazart, за код спасибо, но он не подходит. Более того, длина HTTP запроса зависит от браузера и принимающего сервера и там точно не 127 символов. Через хром можно и 2000+ передать, а вот сколько может обработать сервер arduino за раз я не знаю. Но мне вполне хватит и 500 символов для всех целей.

Та конкретно в Вашем случае как за программировать столько и будет символов, все остальное можно отсекать. 500 символов явно много, лучше используйте POST


Строка в С/С++ это и есть массив символов, только всегда завершающийся терминальным символом равным нулю. А класс String это слишком долгий разговор для форума.

В С++ есть std::string который обычно используется.

Остання редакція Avazart (2019-11-05 12:51:18)

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму