Python telnetlib: удивительная проблема
Я использую модуль telnetlib из Python для создания сессии 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()
Я ничего не получаю (пустая строка). Я могу проверить, что вход выполнен правильно, но по какой-то причине я не вижу текст. Так где же это проглотить?
Большое спасибо.
Для полноты вот логин (хост):
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 ответа
Причина, по которой это работает, когда вы пробуете его вручную, а не в функции, заключается в том, что когда вы пробуете его вручную, у сервера достаточно времени, чтобы отреагировать на вход в систему и отправить данные обратно. Когда все это в одной функции, вы отправляете пароль на сервер и никогда не ждете, пока сервер ответит.
Если вы предпочитаете (возможно, более правильный) технический ответ:
В файле telnetlib.py (c:\python26\Lib\telnetlib.py на моем компьютере с Windows), функция 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 мс, прежде чем вернуть ответ.
У меня та же проблема, что и у вас, к сожалению, комбинация select.select, которая у меня есть в цикле while, пока я не смогу читать, а затем вызов read_some() не работает для меня, все еще только читая 1% фактический вывод. Если я включу time.sleep(10) перед чтением и выполнением read_very_eager(), то это, похоже, сработает... это очень грубый способ сделать что-то, но это сработает. Хотелось бы, чтобы был лучший ответ и Хотелось бы, чтобы у меня было больше очков репутации, чтобы я мог ответить пользователю 387821 и посмотреть, есть ли у него какие-либо дополнительные советы.