ESP-IDF mDNS |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mDNS это широковещательная служба (multicast UDP), которая используется для предоставления локально сетевой службы распознавания имен хоста. mDNS устанавливается по умолчанию на большинстве операционных систем, или её библиотека доступна как отдельный пакет. На Mac OS она устанавливается по умолчанию, и называется Bonjour. Apple выпустила инсталлятор для Windows, который можно найти на страничке поддержки Apple. На Linux mDNS предоставляется avahi, и обычно устанавливается по умолчанию. [Свойства mDNS] hostname: имя устройства, которое будет оно будет отвечать. Если оно не установлено, то hostname будет прочитано из интерфейса. Пример: имя my-esp32 будет разрешаться в my-esp32.local. default_instance: дружественное имя для вашего устройства, наподобие Jhon's ESP32 Thing. Если не установлено, то будет использоваться hostname. Пример запуска mDNS для интерфейса STA, и установка hostname и default_instance: void start_mdns_service() { // Инициализация службы mDNS: esp_err_t err = mdns_init(); if (err) { printf("MDNS Init failed: %d\n", err); return; } // Установка hostname: mdns_hostname_set("my-esp32"); // Установка default instance: mdns_instance_name_set("Jhon's ESP32 Thing"); } [Службы mDNS] mDNS может предоставлять информацию о сетевых службах, которые предоставляет ваше устройство. Каждая служба определяется несколькими свойствами. instance_name: дружественное имя для службы, наподобие Jhon's ESP32 Web Server. Если не определено, то будет использоваться default_instance. service_type: (необходимое свойство) тип службы, добавленное с символом нижнего подчеркивания. Некоторые общие типы можно найти в [2]. proto: (необходимое свойство) протокол, на котором работает служба, символом нижнего подчеркивания. Пример: _tcp или _udp. port: (необходимое свойство) сетевой порт, через который работает служба. txt: {var, val} массив строк, используемый для определения вашей службы. Пример добавления нескольких служб и различных свойств: void add_mdns_services() { // Добавление служб: mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0); mdns_service_add(NULL, "_arduino", "_tcp", 3232, NULL, 0); mdns_service_add(NULL, "_myservice", "_udp", 1234, NULL, 0); // ПРИМЕЧАНИЕ: службы должны быть сначала добавлены, чтобы можно было // установить их свойства. // Настройка пользовательского экземпляра web-сервера. mdns_service_instance_name_set("_http", "_tcp", "Jhon's ESP32 Web Server"); mdns_txt_item_t serviceTxtData[3] = { {"board","{esp32}"}, {"u","user"}, {"p","password"} }; // Установка данных txt для службы (освободит и заменит текущие данные): mdns_service_txt_set("_http", "_tcp", serviceTxtData, 3); // Изменение сетевого порта службы: mdns_service_port_set("_myservice", "_udp", 4321); } [mDNS Query] mDNS предоставляет методы для браузинга служб и распознавания IP-адресов (IPv4/IPv6) хоста. Результаты возвращаются в виде связанного списка объектов mdns_result_t. Пример распознавания IP хоста: void resolve_mdns_host(const char * host_name) { printf("Query A: %s.local", host_name); struct ip4_addr addr; addr.addr = 0; esp_err_t err = mdns_query_a(host_name, 2000, &addr); if(err){ if(err == ESP_ERR_NOT_FOUND){ printf("Host was not found!"); return; } printf("Query Failed"); return; } printf(IPSTR, IP2STR(&addr));
}
Пример распознавания локальных служб: static const char * if_str[] = {"STA", "AP", "ETH", "MAX"}; static const char * ip_protocol_str[] = {"V4", "V6", "MAX"}; void mdns_print_results(mdns_result_t * results) { mdns_result_t * r = results; mdns_ip_addr_t * a = NULL; int i = 1, t; while(r){ printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]); if(r->instance_name){ printf(" PTR : %s\n", r->instance_name); } if(r->hostname){ printf(" SRV : %s.local:%u\n", r->hostname, r->port); } if(r->txt_count){ printf(" TXT : [%u] ", r->txt_count); for(t=0; t<r->txt_count; t++){ printf("%s=%s; ", r->txt[t].key, r->txt[t].value); } printf("\n"); } a = r->addr; while(a){ if(a->addr.type == IPADDR_TYPE_V6){ printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6)); } else { printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4))); } a = a->next; } r = r->next; } } void find_mdns_service(const char * service_name, const char * proto) { ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto); mdns_result_t * results = NULL; esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results); if(err){ ESP_LOGE(TAG, "Query Failed"); return; } if(!results){ ESP_LOGW(TAG, "No results found!"); return; } mdns_print_results(results); mdns_query_results_free(results); } Пример использования этих методов: void my_app_some_method() { // Поиск esp32-mdns.local: resolve_mdns_host("esp32-mdns"); // Поиск серверов HTTP: find_mdns_service("_http", "_tcp"); // ... или файловых серверов: find_mdns_service("_smb", "_tcp"); // общий доступ к файлам Windows find_mdns_service("_afpovertcp", "_tcp"); // общий доступ к файлам Apple find_mdns_service("_nfs", "_tcp"); // сервер NFS find_mdns_service("_ftp", "_tcp"); // сервер FTP // ... или сетевого принтера: find_mdns_service("_printer", "_tcp"); find_mdns_service("_ipp", "_tcp"); } [Оптимизация производительности] Cкорость выполнения. mDNS создает задачу, и по делает это умолчанию с низким приоритетом 1 (опция CONFIG_MDNS_TASK_PRIORITY), если опция CONFIG_FREERTOS_UNICORE разрешена и прикреплена к CPU0 (CONFIG_MDNS_TASK_AFFINITY). Подробнее про оптимизацию скорости см. [3]. Использование RAM. mDNS создает задачи с размерами стека, сконфигурированным опцией CONFIG_MDNS_TASK_STACK_SIZE. Подробнее про оптимизацию использования ОЗУ см. [4]. Пример использования mDNS см. в папке examples репозитория mDNS [5]. [API mDNS]
Полное описание параметров и возвращаемых результатов из этих API-функций, а также связанных с ними макросов, перечислений и типов см. документацию [1]. [Ссылки] 1. ESP-IDF mDNS Service site:espressif.github.io. |