Python telnetlib:令人惊讶的问题

3

我正在使用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

1
我发现,如果我使用read_until()而不是read_very_eager(),它确实可以工作。这可能与协议和数据传输方式有关,而我没有必要的技术背景。 - ptz
2个回答

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], [], [])

这个功能非常简单:如果有任何数据可以从套接字中读取(服务器已经回应),它将返回True,否则返回False。
那么,read_very_eager(self)的作用是:检查是否有可读取的内容。如果有,就从套接字中读取,否则返回一个空字符串。
如果你看一下read_some(self)的代码,你会发现它并没有检查是否有可读取的数据。它会一直尝试读取,直到有可用的数据为止,这意味着如果服务器在回答你之前花费了100毫秒的时间,它将等待100毫秒才返回答案。

3

很抱歉,我和你一样遇到了麻烦。我使用了select.select的组合,在while循环中读取数据,然后调用read_some()函数,但是对于我来说并没有起作用,只能读取实际输出的1%。如果在读取之前加上time.sleep(10),并且使用read_very_eager()函数似乎可以解决问题...这种方法非常粗糙,但它确实有效。我希望有更好的解决方案,也希望我有更多的声誉点数,这样我就可以回复user387821并看看他是否有其他提示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接