ESP8266:Прошивки/Arduino/Библиотеки/Библиотека ESP8266WiFi/Класс клиента/Загрузка содержимого веб-страницы в монитор порта: различия между версиями

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
 
Нет описания правки
Строка 21: Строка 21:
Подключившись к сети, нужно подключиться к серверу. Веб-адрес сервера нужно указать в символьной строке '''host''':
Подключившись к сети, нужно подключиться к серверу. Веб-адрес сервера нужно указать в символьной строке '''host''':


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
const char* host = "www.example.com";
const char* host = "www.example.com";
</syntaxhighlight>
</syntaxhighlight>
Строка 33: Строка 33:
Теперь нам нужно объявить [[клиент]]а, который будет контактировать с [[хост]]ом ([[сервер]]ом):
Теперь нам нужно объявить [[клиент]]а, который будет контактировать с [[хост]]ом ([[сервер]]ом):


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
WiFiClient client;
WiFiClient client;
</syntaxhighlight>
</syntaxhighlight>
Строка 41: Строка 41:
В следующей строчке подключаемся к [[хост]]у и проверяем результат подключения. Обратите внимание на цифру '''«80»'''; это стандартный номер порта, используемый для веб-доступа.
В следующей строчке подключаемся к [[хост]]у и проверяем результат подключения. Обратите внимание на цифру '''«80»'''; это стандартный номер порта, используемый для веб-доступа.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
if (client.connect(host, 80))
if (client.connect(host, 80))
{
{
Строка 56: Строка 56:
Если подключение было выполнено успешно, мы должны отправить [[хост]]у запрос на получение необходимой информации. Это делается при помощи запроса [[HTTP]] [[GET]]:
Если подключение было выполнено успешно, мы должны отправить [[хост]]у запрос на получение необходимой информации. Это делается при помощи запроса [[HTTP]] [[GET]]:


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
client.print(String("GET /") + " HTTP/1.1\r\n" +
client.print(String("GET /") + " HTTP/1.1\r\n" +
             "Host: " + host + "\r\n" +
             "Host: " + host + "\r\n" +
Строка 68: Строка 68:
Затем, пока клиент и [[сервер]] будут подключены друг к другу, строчка за строчкой считываем и печатаем ответ от [[сервер]]а:
Затем, пока клиент и [[сервер]] будут подключены друг к другу, строчка за строчкой считываем и печатаем ответ от [[сервер]]а:


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
while (client.connected())
while (client.connected())
{
{
Строка 87: Строка 87:
Ниже – полна версия скетча, включая фрагмент на тот случай, если соединение с сервером будет закрыто.
Ниже – полна версия скетча, включая фрагмент на тот случай, если соединение с сервером будет закрыто.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
#include <ESP8266WiFi.h>
#include <ESP8266WiFi.h>


Строка 165: Строка 165:
Загружаем скетч на модуль и открываем монитор порта. В нем должна появиться примерно такая запись:
Загружаем скетч на модуль и открываем монитор порта. В нем должна появиться примерно такая запись:


<syntaxhighlight lang="bash" enclose="div">
<syntaxhighlight lang="bash">
Connecting to sensor-net ........ connected
Connecting to sensor-net ........ connected


Строка 175: Строка 175:
Получив запрос, сервер сначала ответит заголовком, в котором будет информация о типе отправляемых данных (например, '''Content-Type: text/html'''), их размере (вроде '''Content-Length: 1270''') и т.д.
Получив запрос, сервер сначала ответит заголовком, в котором будет информация о типе отправляемых данных (например, '''Content-Type: text/html'''), их размере (вроде '''Content-Length: 1270''') и т.д.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
[Response:]
[Response:]
HTTP/1.1 200 OK
HTTP/1.1 200 OK
Строка 195: Строка 195:
Конец заголовка будет помечен пустой строкой, после чего вы должны увидеть [[HTML]]-код запрошенной веб-страницы.
Конец заголовка будет помечен пустой строкой, после чего вы должны увидеть [[HTML]]-код запрошенной веб-страницы.


<syntaxhighlight lang="html5" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="html5" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
<!doctype html>
<!doctype html>
<html>
<html>
Строка 227: Строка 227:
Если адрес веб-сервера будет неверен или если сервер будет недоступен, в мониторе порта должно появиться следующее сообщение:
Если адрес веб-сервера будет неверен или если сервер будет недоступен, в мониторе порта должно появиться следующее сообщение:


<syntaxhighlight lang="c" enclose="div">  
<syntaxhighlight lang="c">  
Connecting to sensor-net ........ connected
Connecting to sensor-net ........ connected



Версия от 19:55, 23 мая 2023

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Черновик


Загрузка содержимого веб-страницы в монитор порта[1]

Давайте напишем простую клиентскую программу, получающей доступ к веб-странице, а затем выгружающей ее содержимое в монитор порта IDE Arduino. То есть операция вполне стандартная – клиент получает доступ к API сервера и извлекает определенную информацию. Класс клиента можно использовать, к примеру, для периодической проверки количества открытых задач в GitHub-репозитории Arduino-аддона ESP8266.

Введение

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

Подключение к WiFi

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

Выбор сервера

Подключившись к сети, нужно подключиться к серверу. Веб-адрес сервера нужно указать в символьной строке host:

const char* host = "www.example.com";

Как видите, в моем случае адресом сервера является доменное имя «www.example.com», но вы можете выбрать любое другое. Впрочем, сначала проверьте, можно ли получить к нему доступ из веб-браузера:

Создаем экземпляр класса WiFiClient

Теперь нам нужно объявить клиента, который будет контактировать с хостом (сервером):

WiFiClient client;

Подключение к серверу

В следующей строчке подключаемся к хосту и проверяем результат подключения. Обратите внимание на цифру «80»; это стандартный номер порта, используемый для веб-доступа.

if (client.connect(host, 80))
{
  // подключились к хосту!
}
else
{
  // подключиться к хосту не удалось
}

Запрос данных

Если подключение было выполнено успешно, мы должны отправить хосту запрос на получение необходимой информации. Это делается при помощи запроса HTTP GET:

client.print(String("GET /") + " HTTP/1.1\r\n" +
             "Host: " + host + "\r\n" +
             "Connection: close\r\n" +
             "\r\n"
            );

Считывание ответа от сервера

Затем, пока клиент и сервер будут подключены друг к другу, строчка за строчкой считываем и печатаем ответ от сервера:

while (client.connected())
{
  if (client.available())
  {
    String line = client.readStringUntil('\n');
    Serial.println(line);
  }
}

При помощи строчки while (client.connected()) проверяем, сохраняется ли подключение между клиентом и сервером. Далее в строчке if (client.available()) проверяем, есть ли у сервера какие-нибудь данные. Если есть, они будут напечатаны в мониторе порта.

После того, как сервер отправит все запрошенные данные, он отключится, а скетч выйдет из цикла while().

Скетч целиком

Ниже – полна версия скетча, включая фрагмент на тот случай, если соединение с сервером будет закрыто.

#include <ESP8266WiFi.h>

const char* ssid = "********";
const char* password = "********";

const char* host = "www.example.com";


void setup()
{
  Serial.begin(115200);
  Serial.println();

  Serial.printf("Connecting to %s ", ssid);
            //  "Подключение к "
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" connected");
             //  " подключено"

}


void loop()
{
  WiFiClient client;

  Serial.printf("\n[Connecting to %s ... ", host);
            //  "Подключение к "

  if (client.connect(host, 80))
  {
    Serial.println("connected]");
               //  " подключено"

    Serial.println("[Sending a request]");
               //  "Отправка запроса"
    client.print(String("GET /") + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
             //  "Хост: "
                 "Connection: close\r\n" +
             //  "Соединение: закрыто"
                 "\r\n"
                );

    Serial.println("[Response:]");
               //  "Ответ:"
    while (client.connected())
    {
      if (client.available())
      {
        String line = client.readStringUntil('\n');
        Serial.println(line);
      }
    }
    client.stop();
    Serial.println("\n[Disconnected]");
               //  "Отключено"
  }
  else
  {
    Serial.println("connection failed!]");
               //  "подключиться не удалось!"
    client.stop();
  }
  delay(5000);
}

Проверка в действии

Загружаем скетч на модуль и открываем монитор порта. В нем должна появиться примерно такая запись:

Connecting to sensor-net ........ connected

[Connecting to www.example.com ... connected]
[Sending a request]

Сначала, когда установится WiFi-соединение, вы должны увидеть подтверждение, что клиент подключился к серверу и отправил ему запрос: Получив запрос, сервер сначала ответит заголовком, в котором будет информация о типе отправляемых данных (например, Content-Type: text/html), их размере (вроде Content-Length: 1270) и т.д.

[Response:]
HTTP/1.1 200 OK

Cache-Control: max-age=604800
Content-Type: text/html
Date: Sat, 30 Jul 2016 12:30:45 GMT
Etag: "359670651+ident"
Expires: Sat, 06 Aug 2016 12:30:45 GMT
Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
Server: ECS (ewr/15BD)
Vary: Accept-Encoding
X-Cache: HIT
x-ec-custom-error: 1
Content-Length: 1270
Connection: close

Конец заголовка будет помечен пустой строкой, после чего вы должны увидеть HTML-код запрошенной веб-страницы.

<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">

(...)

</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is established to be used for illustrative examples in documents. You may use this
    domain in examples without prior coordination or asking for permission.</p>
    <p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

[Disconnected]

Дополнительная проверка

Если адрес веб-сервера будет неверен или если сервер будет недоступен, в мониторе порта должно появиться следующее сообщение:

 
Connecting to sensor-net ........ connected

[Connecting to www.wrong-example.com ... connection failed!]

Итого

Этот пример демонстрирует, как настроить клиентскую программу, подключить ее к серверу, запросить веб-страницу и извлечь ее данные. Это позволит вам написать собственную клиентскую программу для ESP8266, а затем перейти к более сложным диалогам с сервером вроде использования протокола HTTPS при помощи класса безопасного клиента.

Еще примеры:

Список функций, предназначенных для управления клиентом, ищите по [ссылка этой ссылке].

См.также

Внешние ссылки