docs: public synchronized void start() throws SocketException {
  
          if (!isRunning()) {
              socket.set(new DatagramSocket(ANNOUNCEMENT_PORT));
              startTime.set(System.currentTimeMillis());
              deliverLifecycleAnnouncement(logger, true);
  
              final byte[] buffer = new byte[512];
              final DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
              Thread receiver = new Thread(null, new Runnable() {
                  @Override
                  public void run() {
                      boolean received;
                      while (isRunning()) {
                          try {
                              if (getCurrentDevices().isEmpty()) {
                                  socket.get().setSoTimeout(60000);  // We have no devices to check for timeout; block for a whole minute to check for shutdown
                              } else {
                                  socket.get().setSoTimeout(1000);  // Check every second to see if a device has vanished
                              }
                              socket.get().receive(packet);
                              received = !ignoredAddresses.contains(packet.getAddress());
                          } catch (SocketTimeoutException ste) {
                              received = false;
                          } catch (IOException e) {
                              // Don't log a warning if the exception was due to the socket closing at shutdown.
                              if (isRunning()) {
                                  // We did not expect to have a problem; log a warning and shut down.
                                  logger.warn("Problem reading from DeviceAnnouncement socket, stopping", e);
                                  stop();
                              }
                              received = false;
                          }
                          try {
                              if (received && (packet.getLength() == 54)) {
                                  final Util.PacketType kind = Util.validateHeader(packet, ANNOUNCEMENT_PORT);
                                  if (kind == Util.PacketType.DEVICE_KEEP_ALIVE) {
                                      // Looks like the kind of packet we need
                                      if (packet.getLength() < 54) {
                                          logger.warn("Ignoring too-short " + kind.name + " packet; expected 54 bytes, but only got " +
                                                  packet.getLength() + ".");
                                      } else {
                                          if (packet.getLength() > 54) {
                                              logger.warn("Processing too-long " + kind.name + " packet; expected 54 bytes, but got " +
                                                      packet.getLength() + ".");
                                          }
                                          DeviceAnnouncement announcement = new DeviceAnnouncement(packet);
                                          final boolean foundNewDevice = isDeviceNew(announcement);
                                          updateDevices(announcement);
                                          if (foundNewDevice) {
                                              deliverFoundAnnouncement(announcement);
                                          }
                                      }
                                  }
                              }
                              expireDevices();
                          } catch (Throwable t) {
                              logger.warn("Problem processing DeviceAnnouncement packet", t);
                          }
                      }
                  }
              }, "beat-link DeviceFinder receiver");
              receiver.setDaemon(true);
              receiver.start();
          }
      }