8

I'm having a hard time understanding how the recv() function works.

http://docs.paramiko.org/en/1.13/api/channel.html#paramiko.channel.Channel.recv

I understand this is receiving a chunk a data each time you call the function, but can someone elaborate on the structure or size of this data? Lets say I send a command date, I notice:

  • 1st read gets: "date"
  • 2nd read gets: actual response (Mon Jun 9 12:04:17 CDT 2014)
  • 3rd read gets: prompt

But how does this handle debugging messages that appear randomly on the terminal?

Does the previous pattern hold true as long as the actual response is less than maximum bytes (nbytes)?

What happens if it exceeds nbytes?

As per request, I've added a snippet of the code below:

while reads<maxReads:
   resp = self.__chan.recv(maxBytes)
   print resp
   self.__buffer += resp
   if resp.endswith('$ ') or resp.endswith('# '):
      break
   reads += 1
Cristik
  • 30,989
  • 25
  • 91
  • 127
user3388884
  • 4,748
  • 9
  • 25
  • 34
  • 1
    It should receive up to nbytes. Anything larger and it would take up to the max byte chunk. Anything less and it will return everything since it is less than the max size. The next time you call channel.recv it will continue where that last bite left off. It doesn't matter where in the command it left off it will merely take up to the max number of bytes specified. Any prompts that are put out to stderr would need to use recv_stderr. Not sure if that answers your question. – Bob Jun 09 '14 at 17:10
  • ummm one of them :) ... Sending a command, and calling recv next gets me the command itself rather than the real response – user3388884 Jun 09 '14 at 17:12
  • can we see the code where you send and recv? It may be something simple in how you wrote it you may have not noticed. – MikeRixWolfe Jun 09 '14 at 17:36

1 Answers1

3

Channel recv() corresponds to a socket.recv(), it does not have any specific structure or size, it just reads whatever data was sent from the remote server, not exceeding maxBytes.

You commonly use recv() in a loop until you get a piece of data that you are waiting for:

def _wait_for_data(self, options, verbose=False):
    chan = self.chan
    data = ""
    while True:
        x = chan.recv(1024)
        if len(x) == 0:
            self.log("*** Connection terminated\r")
            sys.exit(3)
        data += x
        if verbose:
            sys.stdout.write(x)
            sys.stdout.flush()
        for i in range(len(options)):
            if re.search(options[i], data):
                return i
    return -1
João Pinto
  • 5,521
  • 5
  • 21
  • 35