Skip to main content
 首页 » 编程设计

python telnetlib 模块 : reading and waiting for responses

2025年05月04日19lhb25

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

Python telnetlib: surprising problem

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

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

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

请您参考如下方法:

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

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

  • 事实证明,并非所有出现在服务器端的输出都可供客户端读取。在我使用 asynchat 作为第二意见之前,我不知道这是一件可能发生的事情,并且发现无论我如何发送它,我仍然没有收到来自“print 'Complete Command'”的输出。 (我试图写“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 = []