When you surf on the Internet, the DNS (Domain Name System) service has the job of “translating” (resolve) the hostnames to the corresponding IP addresses.
If, for example, you type www.google.com in your favorite browser, your computer queries the DNS server – usually the one managed by your provider – and gets from it the IP address of (one of) the servers that host Google website:
A home network usually doesn’t include a DNS server, so if you need to communicate with a device you must know its IP address. It may be easy to find the address of a device if such address is statically assigned or if the device itself has a display that can show it:
On the contrary, if the IP address is dynamically assigned (for example by the DHCP server running on your router) and the device can’t display it, it may be hard to find which is the address of the device. It may help the Multicast DNS (mDNS) protocol; let’s learn how to use it with our esp32 chip.
mDNS
mDNS is a network protocol, defined in RFC6762, which allows to resolve hostnames without the need of a DNS server in the network.
Its behavior is very simple. When a device needs to know the IP address of another device on the network, it sends a multicast UDP packet with the request. Since it is a multicast packet, it reaches all the devices connected to the network. The response is again sent out using a multicast packet, so all the devices can receive it and update their resolving table:
By default, mDNS resolves only hostnames with the .local suffix.
ESP32
The esp-idf framework esp-idf includes a component that implements the mDNS protocol; in this tutorial I’ll explain how to use it to answer mDNS queries. The complete source code is available in my Github repository; let’s analyse the most important part.
First of all, using the menuconfig you can configure two parameters:
MDNS_HOSTNAME is the hostname that will be resolved by the esp32 chip (for example “esp32“) while MDNS_INSTANCE is a description of the device (es. “ESP32 Demo Board“).
It’s very easy to setup the mDNS server that answers incoming queries. After having established the connection to the wifi network (this part of the program is based on a previous example) you have only to create a new instance of the server and configure it with the parameters defined above:
// mDNS server instance mdns_server_t* mDNS = NULL; [...] // create and configure the mDNS server ESP_ERROR_CHECK(mdns_init(TCPIP_ADAPTER_IF_STA, &mDNS)); ESP_ERROR_CHECK(mdns_set_hostname(mDNS, CONFIG_MDNS_HOSTNAME)); ESP_ERROR_CHECK(mdns_set_instance(mDNS, CONFIG_MDNS_INSTANCE)); |
Do not forget to include the component’s header at the top of your code:
#include "mdns.h" |
That’s all! When you run the program, the mDNS server waits for incoming requests and, if those requests are for the name MDNS_HOSTNAME.local, it answers with the IP address of your board.
mDNS for Windows and Linux
To be able to test the program, your computer has to “speak” the mDNS protocol.
If you’re running Windows, you can install the Bonjour Print Services tool from Apple. Even if it was designed to discovery and configure network printers (hence its name), this service does support the full mDNS protocol and it’s therefore the best solution with Microsoft OSes.
Under Linux, you can use the Avahi daemon, that is usually already installed on the most common distributions.
After having configured your PC, you can test the program with the command ping esp32.local (change the name with the one you configured):
Conclusion
Using the mDNS component, you can design devices, based on the esp32 chip, that can be easily identified on the network, without the need to add external components like a display or a serial connection. Moreover it’s simpler, specially for non-expert users, to use a standard name (“esp32.local”) then looking for a “strange number” (the IP address) that can also change over time.
In this tutorial I’ve only explained how to write a program that answers mDNS queries: this is the most common use of the protocol but it’s not the only one: the component included in the framework also allows to send queries or to broadcast different services… Espressif published a sample program that leverages also some of these features.
Hi Luca.
I try to compile this example (09_mdns) direct download from your GIT, but I don’t be able to do the “make”.
“uknown type ‘mdns_server_t'”.
In you GIT example, where is locate the “mdns.h”?
Thanks a lot.
Hi Sergi, unfortunately ESP changed the way they handle the mDNS component, I have to change my code accordingly
Hi Luca,
For resolve the problem you need to make the following:
// mdns_server_t* mDNS = NULL;
// ESP_ERROR_CHECK(mdns_init(TCPIP_ADAPTER_IF_STA, &mDNS));
// ESP_ERROR_CHECK(mdns_set_hostname(mDNS, “esp32”));
// ESP_ERROR_CHECK(mdns_set_instance(mDNS, “Basic HTTP Server”));
ESP_ERROR_CHECK(mdns_init());
ESP_ERROR_CHECK(mdns_hostname_set(“esp32”));
ESP_ERROR_CHECK(mdns_instance_name_set(“Basic HTTP Server”));
This is actual for 3 your samples.
thanks! I’ll update my examples accordingly
Ciao Luca,
sto lavorando su VirtualBox – Ubuntu e ho questo errore: “ping: esp32.local: Name or service not known”
Può essere dovuto al fatto che sono su macchina virtuale o sbaglio altro?
ciao Angelo, non so se Ubuntu ha incluso Avahi… ti serve per poter gestire mDNS