start method

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

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) {
    _sockets.add(incoming);
  } else {
    _toBeClosed.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) {
    // Create a socket for sending on each adapter.
    final InternetAddress targetAddress = interface.addresses[0];
    final RawDatagramSocket socket = await _rawDatagramSocketFactory(
      targetAddress,
      selectedMDnsPort,
      reuseAddress: true,
      reusePort: true,
      ttl: 255,
    );
    _sockets.add(socket);
    // Ensure that we're using this address/interface for multicast.
    if (targetAddress.type == InternetAddressType.IPv4) {
      socket.setRawOption(RawSocketOption(
        RawSocketOption.levelIPv4,
        RawSocketOption.IPv4MulticastInterface,
        targetAddress.rawAddress,
      ));
    } else {
      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;
}