start method

Future<void> start({
  1. InternetAddress? listenAddress,
  2. NetworkInterfacesFactory? interfacesFactory,
  3. int mDnsPort = mDnsPort,
  4. InternetAddress? mDnsAddress,
})
inherited

Start the mDNS client.

With no arguments, this method will listen on the IPv4 multicast address on all IPv4 network interfaces.

The listenAddress parameter must be either InternetAddress.anyIPv4 or InternetAddress.anyIPv6, and will default to anyIPv4.

The interfaceFactory defaults to allInterfacesFactory.

The mDnsPort allows configuring what port is used for the mDNS query. If not provided, defaults to 5353.

The mDnsAddress allows configuring what internet address is used for the mDNS query. If not provided, defaults to either 224.0.0.251 or or FF02::FB.

Subsequent calls to this method are ignored while the mDNS client is in started state.

Implementation

Future<void> start({
  InternetAddress? listenAddress,
  NetworkInterfacesFactory? interfacesFactory,
  int mDnsPort = mDnsPort,
  InternetAddress? mDnsAddress,
}) async {
  listenAddress ??= InternetAddress.anyIPv4;
  interfacesFactory ??= allInterfacesFactory;

  assert(listenAddress.address == InternetAddress.anyIPv4.address ||
      listenAddress.address == InternetAddress.anyIPv6.address);

  if (_started || _starting) {
    return;
  }
  _starting = true;

  final int selectedMDnsPort = _mDnsPort = mDnsPort;
  _mDnsAddress = mDnsAddress;

  // Listen on all addresses.
  final RawDatagramSocket incoming = await _rawDatagramSocketFactory(
    listenAddress.address,
    selectedMDnsPort,
    reuseAddress: true,
    reusePort: true,
    ttl: 255,
  );

  // Can't send to IPv6 any address.
  if (incoming.address != InternetAddress.anyIPv6) {
    _incomingIPv4 = incoming;
  } else {
    _ipv6InterfaceSockets.add(incoming);
  }

  _mDnsAddress ??= incoming.address.type == InternetAddressType.IPv4
      ? mDnsAddressIPv4
      : mDnsAddressIPv6;

  final List<NetworkInterface> interfaces =
      (await interfacesFactory(listenAddress.type)).toList();

  for (final NetworkInterface interface in interfaces) {
    final InternetAddress targetAddress = interface.addresses[0];

    // Ensure that we're using this address/interface for multicast.
    if (targetAddress.type == InternetAddressType.IPv6) {
      final RawDatagramSocket socket = await _rawDatagramSocketFactory(
        targetAddress,
        selectedMDnsPort,
        reuseAddress: true,
        reusePort: true,
        ttl: 255,
      );
      _ipv6InterfaceSockets.add(socket);
      socket.setRawOption(RawSocketOption.fromInt(
        RawSocketOption.levelIPv6,
        RawSocketOption.IPv6MulticastInterface,
        interface.index,
      ));
    }

    // Join multicast on this interface.
    incoming.joinMulticast(_mDnsAddress!, interface);
  }
  incoming.listen((RawSocketEvent event) => _handleIncoming(event, incoming));
  _started = true;
  _starting = false;
}