timeout: ping3 сразу отдает значение false

помогите с ping3, задаю параметр timeout=20:

from ping3 import ping
otvet =  ping('10.200.231.203', timeout=20, ttl=20)
print(otvet)

Если ответ приходит Ответ от 10.8.8.150: Заданный узел недоступен, то значение otvet становится False сразу.

Ответ от 10.200.231.203: число байт=32 время=94мс TTL=62
Ответ от 10.200.231.203: число байт=32 время=86мс TTL=62
Ответ от 10.200.231.203: число байт=32 время=82мс TTL=62
Ответ от 10.200.231.203: число байт=32 время=103мс TTL=62
Ответ от 10.200.231.203: число байт=32 время=87мс TTL=62
Превышен интервал ожидания для запроса.
Ответ от 10.8.8.150: Заданный узел недоступен.
Превышен интервал ожидания для запроса.
Ответ от 10.8.8.150: Заданный узел недоступен.
Превышен интервал ожидания для запроса.

Как сделать, если полноценного ответа не приходит, то он пытается достучаться в любом случае до него в течении 20 секунд?

Существующий цикл, в котором хотелось бы использовать цикл исключения:

def ping_complexes(row_size):
    try:
        records = Mangustes.query.limit(row_size).all()
        for record in records:
            if ping(record.ip, timeout=20, ttl=3) in (None, False):
                print('Offline: '+record.ip)
                record.Status = 'Offline'
            else:
                print('Online: ', record.ip)
                record.Status = 'Online'
        db.session.commit()
    except Exception as e:
        print("???", e)

Попытка с доп. функцией:

def ping_complexes(row_size):
    try:
        records = Mangustes.query.limit(row_size).all()
        for record in records:
            if pinger in (None, False):
                print('Offline: '+record.ip)
                record.Status = 'Offline'
            else:
                print('Online: ', record.ip)
                record.Status = 'Online'
        db.session.commit()
    except Exception as e:
        print("???", e)

def pinger():
    while (datetime.datetime.now() - start).total_seconds() < timeout:
        otvet = ping(record.ip, timeout=timeout)
        if otvet:
            break
    return(otvet)

Ответы (1 шт):

Автор решения: CrazyElf

Я вам набросал решение:

from ping3 import ping
import datetime

timeout = 20
start = datetime.datetime.now()
while (datetime.datetime.now() - start).total_seconds() < timeout:
    otvet =  ping('10.200.231.203', timeout=timeout, ttl=20)
    if otvet: # завершаем в случае успеха
        break
print(otvet)

Этот код делает то, что вы хотите. Хотя смысла в этом, мне кажется, не много. Дело в том, что параметр timeout у ping задаёт максимальное время ожидания ответа на запрос. Смысл в том, что если сигнал где-то там долго плутает, чтобы не ждать его бесконечно. В случае же, если наблюдается явная ошибка - например, задан некорректный адрес для пинга или есть проблемы с конфигурацией сети, то ждать тут пингу нечего - ответ уже сразу есть, что мы имеем какую-то ошибку с сетью, понятие таймаута тут никак не применимо. Поэтому в такой ситуации можно только организовать внешний цикл, который будет ожидать либо положительного ответа либо окончания отведённого на запрос времени. Что я и делаю в этом коде. Если сеть бывает падает и через какое-то время поднимается и вы не хотите видеть этого события в результатах работы пинга, а хотите просто переждать этот момент, то этот код вам может помочь. В остальных случаях мне кажется нет смысла ждать чего-то в случае явной ошибки сети.

Update: Если у вас просто есть отдельные выпадения пинга и вы хотите пропустить ошибку (но не более скольки-то раз), то можно просто сделать какое-то число попыток без учёта времени работы кода, это будет проще:

from ping3 import ping

for _ in range(5):
    otvet = ping('10.200.231.203', timeout=20, ttl=20)
    if not (otvet == False): # завершаем если успех или таймаут
        break
print(otvet)

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

→ Ссылка