Python telnetlib: 意外问题

3 投票
2 回答
7523 浏览
提问于 2025-04-16 05:56

我正在使用Python的telnetlib模块来创建一个telnet会话(连接到一个国际象棋服务器),但遇到了一个我实在搞不懂的问题。以下这段代码运行得很好:

>>> f = login("my_server") #code for login(host) below.
>>> f.read_very_eager()

这段代码会输出服务器在登录时通常会打印的所有内容。但是,当我把它放进一个函数里,然后这样调用它:

>>> def foo():
...   f = login("my_server")
...   return f.read_very_eager()
...
>>> foo()

我什么也没得到(返回的是空字符串)。我可以确认登录是成功的,但出于某种原因,我看不到文本。那么,这些信息到底去哪儿了呢?

非常感谢。

为了完整起见,这里是login(host)的代码:

def login(host, handle="guest", password=""):
try:
    f = telnetlib.Telnet(host) #connect to host
except:
    raise Error("Could not connect to host")
f.read_until("login: ")
try:
    f.write(handle + "\n\r")
except:
    raise Error("Could not write username to host")
if handle == "guest":
    f.read_until(":\n\r")
else:
    f.read_until("password: ")
try:
    f.write(password + "\n\r")
except:
    raise Error("Could not write password to host")
return f

2 个回答

3

我遇到的情况和你一样不太好,使用select.select这个方法时,我在一个循环里等着能读取到数据,然后再调用read_some(),结果还是只能读取到实际输出的1%。如果我在读取之前加上time.sleep(10),然后用read_very_eager(),似乎就能正常工作了……虽然这是一种很粗糙的方法,但确实有效。我希望能有更好的解决办法,也希望我有更多的声望积分,这样我就能回复用户387821,看看他有没有其他的建议。

5

这个问题的原因在于,当你手动尝试时,服务器有足够的时间来响应登录请求并发送数据回来。而当所有操作都放在一个函数里时,你把密码发送给服务器后,并没有等足够长的时间去等待服务器的回复。

如果你想要一个(可能更准确的)技术解释:

在文件 telnetlib.py(在我的Windows电脑上是 c:\python26\Lib\telnetlib.py)中,函数 read_very_eager(self) 调用了 self.sock_avail()。现在,函数 sock_avail(self) 的作用是:

def sock_avail(self):
    """Test whether data is available on the socket."""
    return select.select([self], [], [], 0) == ([self], [], [])

这个操作其实很简单:如果我们的套接字(socket)里有任何可以读取的数据(也就是服务器已经回应了),它就会返回 True;否则返回 False。

所以,read_very_eager(self) 的作用是:检查是否有可以读取的数据。如果有,就从套接字中读取数据;如果没有,就返回一个空字符串。

如果你查看 read_some(self) 的代码,你会发现它并没有检查是否有数据可以读取。它会一直尝试读取,直到有数据可用为止,这意味着如果服务器在回应你之前需要100毫秒,它就会等100毫秒再返回结果。

撰写回答