【问题标题】:Python: select() returns immediately without no data to read (telnetlib)Python:select() 立即返回,没有要读取的数据(telnetlib)
【发布时间】:2013-08-26 05:58:37
【问题描述】:

我想使用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

【问题讨论】:

标签: python python-2.7 telnet telnetlib


【解决方案1】:

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

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

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

【讨论】:

  • 我看到了,但不认为这是我的问题。这可以解释不读取数据,但方法 select() 应该被阻止更多时间......
  • 尝试设置tn.set_debuglevel(1) 看看 telnetlib 在做什么。请发布结果。
  • 谢谢!编辑添加带有tn.set_debuglevel(1) 的示例
【解决方案2】:

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

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

Telnet.set_option_negotiation_callback(回调)
每次在输入流上读取 telnet 选项时,都会使用以下参数调用此回调(如果已设置):回调(telnet 套接字,命令(DO/DONT/WILL/WONT),选项)。 telnetlib 之后不会执行任何其他操作。

【讨论】:

  • 完整的解决方法是什么?我尝试通过响应项目来处理谈判,但选择从不阻塞。
猜你喜欢
  • 1970-01-01
  • 2018-11-05
  • 1970-01-01
  • 2019-06-03
  • 2014-01-14
  • 1970-01-01
  • 2011-09-10
  • 2011-12-19
  • 1970-01-01
相关资源
最近更新 更多