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 и посмотреть, есть ли у него какие-либо дополнительные советы.

Другие вопросы по тегам