mDNS Discovery
Discover services and devices on a local network using mDNS (Multicast DNS) / Zeroconf. Zero configuration.
Python Library
pip install zeroconf
Publishing a Service
from zeroconf import Zeroconf, ServiceInfo
import socket
zeroconf = Zeroconf()
info = ServiceInfo(
type_="_myservice._tcp.local.",
name="MyDevice._myservice._tcp.local.",
addresses=[socket.inet_aton("192.168.1.100")],
port=8000,
properties={"version": "1", "name": "My Device"},
)
zeroconf.register_service(info)
Browsing for Services
from zeroconf import Zeroconf, ServiceBrowser, ServiceStateChange
def on_change(zeroconf, service_type, name, state_change):
if state_change == ServiceStateChange.Added:
info = zeroconf.get_service_info(service_type, name)
if info:
device_id = info.properties.get(b"device_id", b"").decode()
host = socket.inet_ntoa(info.addresses[0])
port = info.port
print(f"Found: {name} @ {host}:{port}")
zeroconf = Zeroconf()
browser = ServiceBrowser(zeroconf, "_myservice._tcp.local.", [on_change])
TXT Record Properties
Attach metadata to your service advertisement:
properties={
"device_id": "uuid-here",
"device_name": "My Laptop",
"device_type": "windows",
}
Retrieve on the browsing side:
val = info.properties.get(b"device_id", b"").decode()
Key Patterns
| Pattern | Approach |
|---|---|
| Browse in background | Use ServiceBrowser with callbacks |
| Update properties | Call zeroconf.update_service(info) |
| Remove service | Call zeroconf.unregister_service(info) |
| Filter self | Compare device_id against own ID |
Local IP Helper
def get_local_ip() -> str:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect(("8.8.8.8", 80))
return s.getsockname()[0]
finally:
s.close()
Service Name Convention
Services use the format _<name>._tcp.local.:
_instanttransfer._tcp.local._http._tcp.local._ssh._tcp.local.
Pitfalls
- Same network required — mDNS does not route across subnets
- Firewall — Windows Firewall may block mDNS (UDP 5353)
- VPNs — may interfere with mDNS discovery
- Properties are bytes — keys/values must be under 255 bytes each