Перейти к содержанию

Почему ESP32 со статическим IP не выходит в интернет?

Обновлено Редакция GAW

У устройства в сети IPv4 есть адрес, маска и шлюз, а для работы с именами — ещё адрес DNS-сервера. Пока работает DHCP, всё это выдаёт роутер. При статической настройке каждую величину задаёт программа, и ошибка в любой даёт характерный симптом.

Как устройство решает, куда отправить пакет

Узел накладывает маску на свой адрес и на адрес назначения: если результаты совпадают, получатель в той же сети и пакет уходит напрямую, иначе — через шлюз (RFC 1122, разд. 3.3.1.1). Интернет всегда «не в своей сети», поэтому без правильного шлюза до него не дойти.

СимптомПричина
Не видит и локальную сетьадрес не из подсети роутера или конфликт адресов
Локальная сеть есть, внешних адресов нетшлюз не задан, 0.0.0.0 или не из своей подсети
Внешние IP-адреса доступны, имена — нетне задан DNS-сервер
Часть локальных адресов недоступнамаска шире или уже, чем у роутера

Наш пример: ESP32 с адресом 192.168.1.50/24 и шлюзом 192.168.0.1. Сеть ESP32 — 192.168.1.0, а шлюз лежит в 192.168.0.0: устройство не может отправить ему пакет напрямую, и выхода в интернет нет. Проверить, в одной ли подсети адрес и шлюз, можно в калькуляторе подсетей.

Как задать адрес в ESP-IDF

  1. Остановить клиент DHCP: esp_netif_dhcpc_stop().
  2. Заполнить адрес, маску и шлюз и вызвать esp_netif_set_ip_info().
  3. Задать DNS-сервер: esp_netif_set_dns_info() с типом ESP_NETIF_DNS_MAIN — например, адрес роутера, если он работает DNS-сервером.

Для Ethernet через W5500 или LAN8720 порядок тот же: интерфейс работает через ESP-NETIF — о выборе контроллера ответ «W5500 или LAN8720 для ESP32», а варианты Ethernet для микроконтроллеров — в статье «Ethernet для микроконтроллера».

Похожие вопросы

Как узнать правильный шлюз и маску?

Посмотреть их у компьютера или телефона, подключённого к той же сети и получившего адрес по DHCP: шлюз — адрес роутера, маска — та же. ESP32 со статическим адресом должен получить такие же маску и шлюз и свободный адрес из той же подсети вне пула DHCP роутера.

Почему с DHCP всё работало, а со статическим адресом нет?

При DHCP роутер сам выдаёт адрес, маску, шлюз и DNS-серверы. Остановив DHCP, вы берёте всё это на себя: забытый шлюз отрезает внешние адреса, забытый DNS — имена. По документации ESP-IDF при выключенном клиенте DHCP основной и резервный DNS можно задать только функцией esp_netif_set_dns_info().

esp_netif_set_ip_info() возвращает ошибку. Почему?

Скорее всего, клиент DHCP ещё работает: ESP-IDF требует сначала его остановить функцией esp_netif_dhcpc_stop(), иначе вызов вернёт ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED. Порядок действий показан в примере protocols/static_ip.

Источники

  1. Espressif. ESP-IDF Programming Guide v6.1: ESP-NETIF — для статического адреса и DNS-серверов нужно остановить клиент DHCP, включённый по умолчанию у интерфейса Ethernet и станции Wi-Fi (пример protocols/static_ip); esp_netif_set_ip_info() — адрес, маска и шлюз; esp_netif_set_dns_info(): при включённом DHCP основной и резервный DNS приходят из аренды DHCP, при выключенном — задаются только этой функцией; LWIP хранит DNS глобально, а не для интерфейса
  2. IETF. RFC 1122: Requirements for Internet Hosts — Communication Layers, 1989 — разд. 3.3.1.1: если адрес назначения после наложения маски совпадает с адресом узла, пакет отправляется напрямую, иначе — через шлюз (разд. 3.3.1.2)
  3. Modbus Organization. MODBUS Messaging on TCP/IP Implementation Guide V1.0b, 2006 — разд. 4.3.3.1: адрес шлюза по умолчанию должен быть в подсети локального адреса, 0.0.0.0 запрещён

Нашли ошибку?