1. Introduction
When we visit a website, we usually do so via a URL, such as accessing Baidu through the domain: www.baidu.com
. After entering the domain in the browser, the communication ultimately resolves the domain to the corresponding IP
address, and communication is conducted at the lower level based on the IP
. We don’t need to remember Baidu’s IP
because DNS helps us resolve the domain to the IP
. Thus, if Baidu’s IP
changes, we don’t have to worry as long as we remember the domain.
For ESP32
development, for instance, when we create a TCP server
on ESP32
to listen for services, external clients need to know the IP
address of the ESP32
device beforehand. However, the IP
address assigned to the device by the router is not fixed. If clients could access the device via a domain like they do with Baidu, it would be much more convenient.
So, is there a way to give our ESP32
device a domain name?
The answer is yes, and this brings us to the main character of today: mDNS.
2. What is mDNS (Brief Introduction)
mDNS stands for “Multicast DNS,” a local area network service discovery mechanism. It allows devices to communicate and discover services without a central DNS server, establishing connections within the local area network.
The mDNS protocol uses standard IPv4 and IPv6 multicast addresses, naming local hosts in the local area network using the format hostname.local
. This means devices can automatically assign network addresses and self-configure without needing to manually set each device’s IP
address.
When using the mDNS protocol, devices can discover other devices and services by hostname, sending multicast DNS requests and responses within the local area network. Thus, mDNS allows devices to directly discover each other, providing interoperability without complex configurations or expensive hardware.
In a nutshell: mDNS allows your devices to have a domain name within a local area network, enabling clients to access the device directly via its domain name, with mDNS responsible for resolving the domain to the corresponding IP
, similar to what DNS does.
3. Practical Verification of Truth
Next, we will create a TCP service on the ESP32 platform, start mDNS, and set a domain name. Then, we will use a client (PC) to obtain the IP
through DNS using the domain name for access. If successful, it indicates that the domain name corresponds to the device’s IP
.
3.1. Experimental Conditions:
-
IDF Version: 5.2
-
Hardware: ESP32C3
-
Components Used: espressif/mdns
3.2. Experimental Steps
-
Create the project, directly using the built-in example
>station
; -
Add component: idf.py add-dependency "espressif/mdns^1.2.3"
-
Add code
3.3. Key Code
mDNS Service Setup
void init_esp32_mdns()
{
const char *esp32_host = "alex_esp32";
//initialize mDNS
ESP_ERROR_CHECK( mdns_init() );
//set mDNS domain name
ESP_ERROR_CHECK( mdns_hostname_set(esp32_host) );
ESP_LOGI(TAG, "mdns hostname set to: [%s.local]", esp32_host);
}
TCP Server Creation
#define SERVER_PORT 8080
#define SERVER_BUFFER_SIZE 1024
static void tcp_server_task(void *pvParameters){
char rx_buffer[SERVER_BUFFER_SIZE];
char addr_str[128];
int addr_family;
int ip_protocol;
inet_ntoa_r(dest_addr.sin6_addr, addr_str, sizeof(addr_str) - 1);
int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
if (listen_sock < 0) {
ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
break;
}
ESP_LOGI(TAG, "Socket created");
int err = bind(listen_sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
if (err != 0) {
ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
break;
}
ESP_LOGI(TAG, "Socket bound, port %d", SERVER_PORT);
err = listen(listen_sock, 1);
if (err != 0) {
ESP_LOGE(TAG, "Error occurred while attempting to listen for connections: errno %d", errno);
break;
}
struct sockaddr_in6 source_addr;
uint8_t cnt = 0;
else {
rx_buffer[len] = 0;
ESP_LOGI(TAG, "Received %d bytes: %s", len, rx_buffer);
const char* resp_str = "Hello, TCP Client!";
int resp_len = strlen(resp_str);
int err = send(sock, resp_str, resp_len, 0);
if (err < 0) {
ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
break;
}
}
}
if (sock != -1) {
ESP_LOGE(TAG, "Shutting down socket %d", sock);
shutdown(sock, 0);
close(sock);
}
cnt++;
ESP_LOGI(TAG, "Socket %d closed. Listening for next connection...", cnt);
}
}
3.4. Experimental Results
-
After starting the device, ping the domain name set for the device to obtain its IP
; -
The computer uses a TCP tool to connect to the IP
obtained in the first step, successfully connecting -
Device logs show that the device received information from the TCP client
Conclusion: The mDNS domain name can be bound to the device’s IP
4. mDNS Supplement
The example above only showcases part of mDNS’s many features; mDNS has many other technical details, such as:
-
Instance Name -
Service Type -
Service Protocol -
Designated Port Number -
Service Attributes, etc. -
Protocol Specification Document rfc6762
(https://datatracker.ietf.org/doc/html/rfc6762)
5. Application Scenario Outlook
-
Used for service discovery within a local area network, such as Apple’s Bonjour
,airplay
which is based onmDNS
; -
IoT device discovery, such as Matter’s local discovery _matter._tcp
-
Many other applications, as shown in the screenshot where I discovered some mDNS services in the current environment