【问题标题】:python telnetlib module: reading and waiting for responsespython telnetlib 模块:读取并等待响应
【发布时间】:2012-10-27 01:40:15
【问题描述】:

我遇到了与此海报类似的问题:

Python telnetlib: surprising problem

请注意下面的回复和我的回复。

在调用任何读取函数时,基本上 telnetlib 不允许我读取整个响应。

在 while 循环中使用 select.select([telnetobject],[],[]) 以确保读取可用后调用 telnet.read_very_eager() 时,我将得到的唯一内容是几个字符。到目前为止,我能想出的唯一解决方案是使用 time.sleep() ,但它的解决方案太粗糙了,我正在寻找更适合的解决方案。任何帮助表示赞赏...

【问题讨论】:

    标签: python response wait telnetlib


    【解决方案1】:

    我想我遇到了同样的问题,我希望这些信息会有所帮助。就我而言,我正在连接到 Maya 中的 mel 和 python 端口,所以我不知道这种体验是否对您和您的情况有用。

    • This answer 向我展示了我尝试执行的 I/O 根本不需要 Telnet/telnetlib,并推荐了asynchat

    • 事实证明,并非所有出现在服务器端的输出都可供客户端读取。在我使用 asynchat 作为第二个意见之前,我不知道这是可能发生的事情,并且无论我如何发送它,我仍然没有收到来自“print 'Complete Command'”的输出。 (我试图写“打印'完成命令'”并读取结果以了解我之前的命令何时完成。)

    我最终调用了 mel 的警告命令,它确实产生了客户端可读的输出。发送无辜数据作为警告非常令人反感,但幸运的是这是针对内部工具的。

    • telnetlib 似乎没有对写入进行排队。因此,我计划背靠背发送两个命令(真正的命令,然后是“命令完成”公告)并不总是有效。因此,似乎只有在您确切知道要 read_until() 的输出时,读取 telnetlib 输出才可行,或者您愿意在怀疑输出完成之前睡觉。但是 asynchat.push() 肯定会按预期排队写入。

    一个样本,在我仍在弄清楚这一点时,要与一大粒盐一起采集:

    class mayaClient(asynchat.async_chat) :
    
    
    ... 
    
    def __init__(self, sock, clientType):
    
        asynchat.async_chat.__init__(self, sock=sock)
    
        self.clientType = clientType
        self.ibuffer = []
        self.obuffer = ""
        self.set_terminator("\r\n")
        self.cumulativeResponse = ""
    
    
    @classmethod
    def withSocket(cls, host, clientType, log) :
    
        melSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        portNumber = cls.MEL_PORT_NUMBER if clientType == cls.MEL else cls.PYTHON_PORT_NUMBER
        melSocket.connect((host, portNumber))   
        return cls(melSocket, clientType, log)
    
    
    #############################################################
    # pushAndWait
    #############################################################
    def pushAndWait(self, command, timeout=60) :
        """
        ACTION:     Push a command and a "command complete" indicator
                    If command completed, return number of milliseconds it took
                    If command timed out without completing, return -1
    
        INPUT:      command as string
                    description (optional) as string for more informative logging
                    timeout in seconds as int after which to give up
    
        OUTPUT:     X milliseconds if command completed
                    -1 if not
    
        """
    
        self.found_terminator()
    
        incrementToSleep = .001
    
        self.push("%s\r\n"%command)
    
        responseToSeek = "Command Complete"
        self.push('Whatever command is going to create readable output for %s`); \r\n'%responseToSeek)
    
        timeSlept = 0
        while responseToSeek not in self.currentBufferString() and timeSlept < timeout :
            self.read()
            timeSlept += incrementToSleep
            time.sleep(incrementToSleep)
    
        if responseToSeek in self.currentBufferString() :
            return timeSlept
    
        return -1
    
    
    #############################################################
    # read
    #############################################################
    def read(self) :
        """
        ACTION:     Reads the current available output
                    and stores it in buffer
    
        """
    
        try :
    
            self.collect_incoming_data(self.recv(1024))
    
        except Exception, e :
    
            # Don't worry about it -- just means there's nothing to read
            #
            pass
    
    
    #############################################################
    # currentBuffer
    #############################################################
    def currentBuffer(self) :
    
        return self.ibuffer
    
    
    #############################################################
    # currentBufferString
    #############################################################
    def currentBufferString(self) :
    
        return "".join(self.ibuffer)
    
    
    #############################################################
    # collect_incoming_data
    #############################################################
    def collect_incoming_data(self, data):
        """Buffer the data"""
    
        self.ibuffer.append(data)   
    
    
    #############################################################
    # found_terminator
    #############################################################
    def found_terminator(self):
    
        print "Clearing --%s...-- from buffer"%self.currentBufferString()[0:20]
        self.ibuffer = []
    

    【讨论】:

      【解决方案2】:

      聚会迟到了,但使用 telnetlib 可以做到这一点。下面将读取所有行,直到没有任何内容。 timeout=0.1 增加了响应到达的时间。

      try:
          while True:             # read until we stop
              message = session.read_until(b'\n', timeout=0.1)
              if message == b'':  # check if there was no data to read
                  break           # now we stop
              print(message)      # print message if not stopped
      except EOFError:            # If connection was closed
          print('connection closed')
      

      或者如果你总是想等待响应:

      try:
          message = session.read_until(b'\n') # Will not timeout until you have response
          print(message)
          while True:             # read until we stop
              message = session.read_until(b'\n', timeout=0.1)
              if message == b'':  # check if there was no data to read
                  break           # now we stop
              print(message)      # print message if not stopped
      except EOFError:            # If connection was closed
          print('connection closed')
      

      【讨论】:

      • 我在这里看到了逐行读取输出的要点。但是,如果最后一行不以 cr/lf 结尾,你会怎么做?例如。 telnet 设备可能会输出提示,提示通常不会以 cr/lf 结束。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-29
      • 1970-01-01
      • 1970-01-01
      • 2019-02-16
      • 1970-01-01
      相关资源
      最近更新 更多