Python:select()立即返回,没有数据可读(telnetlib)

时间:2013-08-23 08:41:08

标签: python python-2.7 telnet telnetlib

我想使用select.select()阻止循环,直到准备好从telnet会话列表中读取某些数据。但是,下面的代码不起作用,对select.select()的调用立即返回,没有数据要读取。我在Ubuntu 10.4下使用python 2.7.3。

tn = telnetlib.Telnet(IP,23,TIMEOUT)
# [... logging and password omitted ..]

while True:
    logging.info("%d - waiting on select for data" % self.id)
    read_ready, write_ready, expt_ready = select.select([ tn.get_socket() ],[],[])
    logging.info("%d - select returned" % self.id)
    if len(read_ready) == 1:
        data = tn.read_eager()
        logging.info("%d read %d characters" % (self.id, len(data)))
        # ... continue processing the data...

输出的一个例子:

2013-08-23 10:37:28,634 - INFO: 1 - waiting on select for data
2013-08-23 10:37:28,672 - INFO: 1 - select returned
2013-08-23 10:37:28,673 - INFO: 1 read 0 characters
2013-08-23 10:37:28,833 - INFO: 1 - waiting on select for data
2013-08-23 10:37:28,874 - INFO: 1 - select returned
2013-08-23 10:37:28,874 - INFO: 1 read 0 characters
2013-08-23 10:37:29,029 - INFO: 1 - waiting on select for data
2013-08-23 10:37:29,073 - INFO: 1 - select returned
2013-08-23 10:37:29,074 - INFO: 1 read 0 characters

set_debuglevel(1)的示例:

2013-08-23 11:50:29,019 - INFO: 1 - waiting on select for data
2013-08-23 11:50:29,062 - INFO: 1 - select returned
Telnet(10.2.3.15,23): recv '\xff\xfe\x01'
Telnet(10.2.3.15,23): IAC DONT 1
2013-08-23 11:50:29,062 - INFO: 1 read 0 characters
2013-08-23 11:50:29,063 - INFO: 1 - waiting on select for data
2013-08-23 11:50:29,069 - INFO: 1 - select returned
Telnet(10.2.3.15,23): recv '\xff\xfe!'
Telnet(10.2.3.15,23): IAC DONT 33
2013-08-23 11:50:29,069 - INFO: 1 read 0 characters
2013-08-23 11:50:29,070 - INFO: 1 - waiting on select for data
2013-08-23 11:50:29,110 - INFO: 1 - select returned
Telnet(10.2.3.15,23): recv '\xff\xfc\x03'
Telnet(10.2.3.15,23): IAC WONT 3
2013-08-23 11:50:29,110 - INFO: 1 read 0 characters

2 个答案:

答案 0 :(得分:1)

正如“Stefano M”建议的那样,这个问题与telnet会话选项协商有关。出于某种原因,客户端和服务器不断交换选项,因此select.select()从未被阻止(总是有数据需要读取)。

我通过设置option negotiation callback找到了解决方法。

  

Telnet.set_option_negotiation_callback(回调)
  每次在输入流上读取telnet选项时,将使用以下参数调用此回调(如果已设置):callback(telnet socket,命令(DO / DONT / WILL / WONT),选项)。之后telnetlib没有采取任何其他行动。

答案 1 :(得分:0)

答案在文档中:(pydoc telnetlib):

  

可以将Telnet对象传递给select.select()以便   等到有更多数据可用。请注意,在这种情况下,   即使套接字上有数据,read_eager()也可能返回'',   因为协议协商可能已经吞噬了数据。

从调试输出中可以清楚地看到远程端发送telnet命令而不是实际数据,所以你必须调试telnet握手。