def request(command, messages)
      response = StringIO.new String.new(""), "w"
      response.set_encoding "ASCII-8BIT"
      status   = -1
      version  = 0
      length   = 0
      message  = Riddle.encode(Array(messages).join(""), 'ASCII-8BIT')

      connect do |socket|
        case command
        when :search
          if Versions[command] >= 0x118
            socket.send request_header(command, message.length) +
              [0, messages.length].pack('NN') + message, 0
          else
            socket.send request_header(command, message.length) +
              [messages.length].pack('N') + message, 0
          end
        when :status
          socket.send request_header(command, message.length), 0
        else
          socket.send request_header(command, message.length) + message, 0
        end

        header = socket.recv(8)
        status, version, length = header.unpack('n2N')

        while response.length < (length || 0)
          part = socket.recv(length - response.length)

          # will return 0 bytes if remote side closed TCP connection, e.g, searchd segfaulted.
          break if part.length == 0 && socket.is_a?(TCPSocket)

          response << part if part
        end
      end

      response = response.string

      if response.empty? || response.length != length
        raise ResponseError, "No response from searchd (status: #{status}, version: #{version})"
      end

      case status
      when Statuses[:ok]
        if version < Versions[command]
          puts format("searchd command v.%d.%d older than client (v.%d.%d)",
            version >> 8, version & 0xff,
            Versions[command] >> 8, Versions[command] & 0xff)
        end
        response
      when Statuses[:warning]
        length = response[0, 4].unpack('N*').first
        puts response[4, length]
        response[4 + length, response.length - 4 - length]
      when Statuses[:error], Statuses[:retry]
        message = response[4, response.length - 4]
        klass = message[/out of bounds/] ? OutOfBoundsError : ResponseError
        raise klass, "searchd error (status: #{status}): #{message}"
      else
        raise ResponseError, "Unknown searchd error (status: #{status})"
      end
    end
def request(command, messages)
      response = StringIO.new String.new(""), "w"
      response.set_encoding "ASCII-8BIT"
      status   = -1
      version  = 0
      length   = 0
      message  = Riddle.encode(Array(messages).join(""), 'ASCII-8BIT')

      connect do |socket|
        case command
        when :search
          if Versions[command] >= 0x118
            socket.send request_header(command, message.length) +
              [0, messages.length].pack('NN') + message, 0
          else
            socket.send request_header(command, message.length) +
              [messages.length].pack('N') + message, 0
          end
        when :status
          socket.send request_header(command, message.length), 0
        else
          socket.send request_header(command, message.length) + message, 0
        end

        header = socket.recv(8)
        status, version, length = header.unpack('n2N')

        while response.length < (length || 0)
          part = socket.recv(length - response.length)

          # will return 0 bytes if remote side closed TCP connection, e.g, searchd segfaulted.
          break if part.length == 0 && socket.is_a?(TCPSocket)

          response << part if part
        end
      end

      response = response.string

      if response.empty? || response.length != length
        raise ResponseError, "No response from searchd (status: #{status}, version: #{version})"
      end

      case status
      when Statuses[:ok]
        if version < Versions[command]
          puts format("searchd command v.%d.%d older than client (v.%d.%d)",
            version >> 8, version & 0xff,
            Versions[command] >> 8, Versions[command] & 0xff)
        end
        response
      when Statuses[:warning]
        length = response[0, 4].unpack('N*').first
        puts response[4, length]
        response[4 + length, response.length - 4 - length]
      when Statuses[:error], Statuses[:retry]
        message = response[4, response.length - 4]
        klass = message[/out of bounds/] ? OutOfBoundsError : ResponseError
        raise klass, "searchd error (status: #{status}): #{message}"
      else
        raise ResponseError, "Unknown searchd error (status: #{status})"
      end
    end
Send a collection of messages, for a command type (eg, search, excerpts,
 update), to the Sphinx daemon.