# File lib/Dnsruby/SingleResolver.rb, line 193
    def send_async(msg, client_query_id, client_queue, use_tcp=@use_tcp)
      st = SelectThread.instance
      if (msg.kind_of?String)
        msg = Message.new(msg)
      end
      query_packet = make_query_packet(msg)
      if (udp_packet_size < query_packet.length)
        use_tcp = true
      end
      # First send the query (synchronously)
      # @TODO@ persisent sockets
      endtime = Time.now + @packet_timeout
      socket = nil
      begin
        #@TODO@ Different OSes have different interpretations of "random port" here.
        #Apparently, Linux will just give you the same port as last time, unless it is still
        #open, in which case you get n+1.
        #We need to determine an actual (random) number here, then ask the OS for it, and
        #continue until we get one.
        if (use_tcp) 
          print "Setting src_port to #{@src_port}"
          socket = TCPSocket.new(@server, @port, @src_addr, @src_port)
        else
          socket = UDPSocket.new()
          socket.bind(@src_addr, @src_port)
          socket.connect(@server, @port)
        end
      rescue Exception => e
        if (socket!=nil)
          socket.close
        end
        err=IOError.new("dnsruby can't connect to #{@server}:#{@port} from #{@src_addr}:#{@src_port}, use_tcp=#{use_tcp}, exception = #{e.class}, #{e}")
        TheLog.error("#{err}")
        st.push_exception_to_select(client_query_id, client_queue, err, nil)
        return
      end
      if (socket==nil)
        err=IOError.new("dnsruby can't connect to #{@server}:#{port} from #{@src_addr}:#{@src_port}, use_tcp=#{use_tcp}")
        TheLog.error("#{err}")
        st.push_exception_to_select(client_query_id, client_queue, err, nil)
        return
      end
      TheLog.debug("Sending packet to #{@server}:#{@port} from #{@src_addr}:#{@src_port}, use_tcp=#{use_tcp}")
      begin
        if (use_tcp)
          lenmsg = [query_packet.length].pack('n')
          socket.send(lenmsg, 0)
        end
        socket.send(query_packet, 0)
      rescue Exception => e
        socket.close
        err=IOError.new("Send failed to #{@server}:#{@port} from #{@src_addr}:#{@src_port}, use_tcp=#{use_tcp}, exception : #{e}")
        TheLog.error("#{err}")
        st.push_exception_to_select(client_query_id, client_queue, err, nil)
        return
      end
      
      # Then listen for the response
      query_settings = SelectThread::QuerySettings.new(query_packet, msg.header.id, @tsig_key, @ignore_truncation, client_queue, client_query_id, socket, @server, @port, endtime)
      # The select thread will now wait for the response and send that or a timeout
      # back to the client_queue
      st.add_to_select(query_settings)
    end