code: def _udp_transact(self, payload, handler, *args,
                        broadcast=False, timeout=TIMEOUT):
          
          if self.host in _BUFFER:
              del _BUFFER[self.host]
          host = self.host
          if broadcast:
              host = '255.255.255.255'
          retval = None
          for _ in range(RETRIES):
              _SOCKET.sendto(bytearray(payload), (host, PORT))
              start = time.time()
              while time.time() < start + timeout:
                  data = _BUFFER.get(self.host, None)
                  if data:
                      retval = handler(data, *args)
                  # Return as soon as a response is received
                  if retval:
                      return retval
docs: Complete a UDP transaction.
  
          UDP is stateless and not guaranteed, so we have to
          take some mitigation steps:
          - Send payload multiple times.
          - Wait for awhile to receive response.
  
          :param payload: Payload to send.
          :param handler: Response handler.
          :param args: Arguments to pass to response handler.
          :param broadcast: Send a broadcast instead.
          :param timeout: Timeout in seconds.