<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def send(query, address=DEFAULT_ADDRESS, port=DEFAULT_PORT, ttl=DEFAULT_TTL, local_only=False, timeout_s=2):
 """Sends a query to the given multicast socket and returns responses. Args: query: The string query to send. address: Multicast IP address component of the socket to send to. port: Multicast UDP port component of the socket to send to. ttl: TTL for multicast messages. 1 to keep traffic in-network. timeout_s: Seconds to wait for responses. Returns: A set of all responses that arrived before the timeout expired. Responses are tuples of (sender_address, message). """

  # Set up the socket as a UDP Multicast socket with the given timeout.
  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
  if local_only:
    # Set outgoing interface to localhost to ensure no packets leave this host.
    sock.setsockopt(
        socket.IPPROTO_IP,
        socket.IP_MULTICAST_IF,
        struct.pack('!L', LOCALHOST_ADDRESS))
  sock.settimeout(timeout_s)
  sock.sendto(query.encode('utf-8'), (address, port))

  # Set up our thread-safe Queue for handling responses.
  recv_queue = queue.Queue()
  def _handle_responses():
    while True:
      try:
        data, address = sock.recvfrom(MAX_MESSAGE_BYTES)
        data = data.decode('utf-8')
      except socket.timeout:
        recv_queue.put(None)
        break
      else:
        _LOG.debug('Multicast response to query "%s": %s:%s',
                   query, address[0], data)
        recv_queue.put((address[0], str(data)))

  # Yield responses as they come in, giving up once timeout expires.
  response_thread = threading.Thread(target=_handle_responses)
  response_thread.start()
  while response_thread.is_alive():
    recv_tuple = recv_queue.get()
    if not recv_tuple:
      break
    yield recv_tuple
  response_thread.join()