Python telnetlib: удивительная проблема - PullRequest
3 голосов
/ 23 октября 2010

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

5 голосов
/ 26 января 2011

Причина, по которой это работает, когда вы пробуете его вручную, а не в функции, заключается в том, что, когда вы пробуете его вручную, у сервера достаточно времени, чтобы отреагировать на вход в систему и отправить данные обратно.Когда все в одной функции, вы отправляете пароль на сервер и никогда не ждете, пока сервер ответит.

Если вы предпочитаете (возможно, более правильный) технический ответ:

Вфайл 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], [], [])

Что этоdo действительно прост: если есть что-нибудь- для чтения из нашего сокета (сервер ответил), он вернет True, в противном случае он вернет False.

Итак, что read_very_eager(self) делает, так это: проверьте, есть ли что-нибудь доступное для чтения.Если есть, то читайте из сокета, иначе просто верните пустую строку.

Если вы посмотрите на код read_some(self), вы увидите, что он не проверяет, есть ли какие-либо данные, доступные длячитать.Он будет пытаться читать до тех пор, пока не появится что-то доступное, что означает, что если сервер берет, например, 100 мс, прежде чем ответить вам, он будет ждать 100 мс, прежде чем вернуть ответ.

3 голосов
/ 07 ноября 2012

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

...