Python telnetlib: удивительная проблема

Я использую модуль 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()

Я ничего не получаю (пустая строка). Я могу проверить правильность входа в систему, но почему-то не вижу текста. Так где его проглотить?

Большое спасибо.

Для полноты, вот логин (хост):

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

person ptz    schedule 22.10.2010    source источник
comment
Я обнаружил, что если вместо read_very_eager() я использую, скажем, read_until(), это работает. Это должно быть что-то о протоколах и способах передачи данных, а у меня нет необходимой технической подготовки.   -  person ptz    schedule 23.10.2010


Ответы (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 мс, прежде чем вернуть ответ.

person Mew    schedule 26.01.2011

У меня та же проблема, что и у вас, к сожалению, комбинация select.select, которая у меня есть в цикле while, пока я не смогу читать, а затем вызов read_some() у меня не работает, все еще читая только 1% фактический выход. Если я включу time.sleep(10) до того, как прочитаю и выполню read_very_eager(), это, кажется, сработает... это очень грубый способ сделать что-то, но он действительно работает.. Я бы хотел, чтобы был лучший ответ и Хотелось бы, чтобы у меня было больше очков репутации, чтобы я мог ответить пользователю 387821 и посмотреть, есть ли у него какие-либо дополнительные советы.

person tSs    schedule 07.11.2012