Обнаружить закрытое соединение в telnetlib Python

Я использую Python telnetlib для подключения к удаленному серверу telnet. Мне трудно определить, открыто ли соединение, или удаленный сервер закрыл его для меня.

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

Есть ли способ отправить какой-то пакет «Вы там», не влияя на фактическое соединение? telnet RFC поддерживает команды "вы здесь" и "NOP" - просто не уверен как заставить telnetlib отправлять их!


person zigdon    schedule 12.12.2011    source источник


Ответы (4)


Вы должны иметь возможность отправить NOP следующим образом:

from telnetlib import IAC, NOP

... 

telnet_object.sock.sendall(IAC + NOP)
person David K. Hess    schedule 13.12.2011
comment
Что еще нужно сделать, чтобы обнаружить, что соединение закрыто? Я захватил сокет с помощью socket_ = tn.get_socket(), затем отправил NOP, но никаких исключений не возникло. - person skid; 27.07.2016

Я заметил, что почему-то отправить только один раз было недостаточно... Я "обнаружил" это случайно, у меня было что-то вроде этого:

def check_alive(telnet_obj):
    try:
        if telnet_obj.sock: # this way I've taken care of problem if the .close() was called
           telnet_obj.sock.send(IAC+NOP) # notice the use of send instead of sendall
           return True
    except:
           logger.info("telnet send failed - dead")
           pass

# later on
logger.info("is alive %s", check_alive(my_telnet_obj))
if check_alive(my_telnet_obj):
     # do whatever

после нескольких прогонов я заметил, что в сообщении журнала было написано «живо, правда», но код не ввел «если», и что было напечатано сообщение журнала «telnet send failed - dead», поэтому в моем последней реализации, как я уже говорил здесь, я просто вызываю метод .send() 3 раза (на всякий случай 2 не было достаточно).

Это мои 2 цента, надеюсь, это поможет

person Lohmar ASHAR    schedule 08.02.2017

Следуя решению Дэвида, после close() в интерфейсе атрибут sock меняется с socket._socketobject на целое число 0. Вызов .sendall завершается ошибкой с AttributeError, если сокет закрыт, поэтому вы можете просто проверить его тип.

Проверено с Linux и Windows 7.

person Frank M    schedule 02.10.2015
comment
Подчеркнем, что эту проверку можно использовать только в том случае, если telnet-соединение было закрыто с вашей стороны. Если соединение было закрыто удаленно, тип объекта остается как socket._socketobject, а НЕ целочисленный. - person skid; 27.07.2016

Лучший способ определить, закрыто ли соединение, это объект сокета. Так проще проверить вот так

def is_connected(telnet_obj):
    return telnet_obj.get_socket().fileno()

Если он закрыт, верните -1

Я взял этот код из этого question< /а>.

person Riccardo Amadio    schedule 11.11.2020