Пинг серверы в Python - PullRequest
       182

Пинг серверы в Python

136 голосов
/ 02 июня 2010

Есть ли в Python способ пропинговать сервер через ICMP и возвращать TRUE, если сервер отвечает, или FALSE, если ответа нет?

Ответы [ 26 ]

2 голосов
/ 15 февраля 2018

Программный пинг ICMP сложен из-за повышенных привилегий, необходимых для отправки необработанных ICMP-пакетов, и вызов ping двоичного кода ужасен Для мониторинга сервера вы можете достичь того же результата, используя методику TCP ping :

# pip3 install tcping
>>> from tcping import Ping
# Ping(host, port, timeout)
>>> ping = Ping('212.69.63.54', 22, 60)
>>> ping.ping(3)
Connected to 212.69.63.54[:22]: seq=1 time=23.71 ms
Connected to 212.69.63.54[:22]: seq=2 time=24.38 ms
Connected to 212.69.63.54[:22]: seq=3 time=24.00 ms

Внутренне это просто устанавливает TCP-соединение с целевым сервером и немедленно сбрасывает его, измеряя прошедшее время. Эта конкретная реализация немного ограничена в том, что она не обрабатывает закрытые порты, но для ваших собственных серверов она работает довольно хорошо.

2 голосов
/ 02 декабря 2017

Используя Multi-ping (pip install multiPing) Я сделал этот простой код ( просто скопируйте и вставьте, если хотите! ):

from multiping import MultiPing

def ping(host,n = 0):
    if(n>0):
        avg = 0
        for i in range (n):
            avg += ping(host)
        avg = avg/n
    # Create a MultiPing object to test hosts / addresses
    mp = MultiPing([host])

    # Send the pings to those addresses
    mp.send()

    # With a 1 second timout, wait for responses (may return sooner if all
    # results are received).
    responses, no_responses = mp.receive(1)


    for addr, rtt in responses.items():
        RTT = rtt


    if no_responses:
        # Sending pings once more, but just to those addresses that have not
        # responded, yet.
        mp.send()
        responses, no_responses = mp.receive(1)
        RTT = -1

    return RTT

Использование:

#Getting the latency average (in seconds) of host '192.168.0.123' using 10 samples
ping('192.168.0.123',10)

Если вы хотите одну выборку, второй параметр "10" можно игнорировать!

Надеюсь, это поможет!

2 голосов
/ 28 декабря 2015

В итоге я нашел этот вопрос относительно похожего сценария. Я попробовал pyping, но пример, приведенный Naveen, не работал для меня в Windows под Python 2.7.

Пример, который работал для меня:

import pyping

response = pyping.send('Your IP')

if response['ret_code'] == 0:
    print("reachable")
else:
    print("unreachable")
2 голосов
/ 01 октября 2014
#!/usr/bin/python3

import subprocess as sp

ip = "192.168.122.60"
status,result = sp.getstatusoutput("ping -c1 -w2 " + ip)

if status == 0: 
    print("System " + ip + " is UP !")
else:
    print("System " + ip + " is DOWN !")
1 голос
/ 13 февраля 2018

Вот решение с использованием модуля Python subprocess и инструмента CLI ping, предоставляемого базовой ОС. Проверено на Windows и Linux. Поддержка установки таймаута сети. Не требуются права суперпользователя (по крайней мере, в Windows и Linux).

import platform
import subprocess

def ping(host, network_timeout=3):
    """Send a ping packet to the specified host, using the system "ping" command."""
    args = [
        'ping'
    ]

    platform_os = platform.system().lower()

    if platform_os == 'windows':
        args.extend(['-n', '1'])
        args.extend(['-w', str(network_timeout * 1000)])
    elif platform_os in ('linux', 'darwin'):
        args.extend(['-c', '1'])
        args.extend(['-W', str(network_timeout)])
    else:
        raise NotImplemented('Unsupported OS: {}'.format(platform_os))

    args.append(host)

    try:
        if platform_os == 'windows':
            output = subprocess.run(args, check=True, universal_newlines=True).stdout

            if output and 'TTL' not in output:
                return False
        else:
            subprocess.run(args, check=True)

        return True
    except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
        return False
1 голос
/ 21 декабря 2017

Мне понравилось ping3 https://github.com/kyan001/ping3 Очень просто и удобно!

from ping3 import ping, verbose_ping
ping('example.com')  # Returns delay in seconds.
>>>0.215697261510079666
1 голос
/ 14 февраля 2015

Этот скрипт работает в Windows и должен работать в других ОС: Работает на Windows, Debian и Macosx, требуется тестирование на Solaris.

import os
import platform


def isUp(hostname):

    giveFeedback = False

    if platform.system() == "Windows":
        response = os.system("ping "+hostname+" -n 1")
    else:
        response = os.system("ping -c 1 " + hostname)

    isUpBool = False
    if response == 0:
        if giveFeedback:
            print hostname, 'is up!'
        isUpBool = True
    else:
        if giveFeedback:
            print hostname, 'is down!'

    return isUpBool

print(isUp("example.com")) #Example domain
print(isUp("localhost")) #Your computer
print(isUp("invalid.example.com")) #Unresolvable hostname: https://tools.ietf.org/html/rfc6761
print(isUp("192.168.1.1")) #Pings local router
print(isUp("192.168.1.135")) #Pings a local computer - will differ for your network
1 голос
/ 12 апреля 2019

Моя версия функции ping:

  • Работает на Python 3.5 и более поздних версиях, в Windows и Linux (должен работать на Mac, но не может его протестировать).
  • В Windows возвращает значение False, если команда ping завершается с ошибкой «Целевой хост недоступен».
  • И не показывает никаких выходных данных ни в виде всплывающего окна, ни в командной строке.
import platform, subprocess

def ping(host_or_ip, packets=1, timeout=1000):
    ''' Calls system "ping" command, returns True if ping succeeds.
    Required parameter: host_or_ip (str, address of host to ping)
    Optional parameters: packets (int, number of retries), timeout (int, ms to wait for response)
    Does not show any output, either as popup window or in command line.
    Python 3.5+, Windows and Linux compatible (Mac not tested, should work)
    '''
    # The ping command is the same for Windows and Linux, except for the "number of packets" flag.
    if platform.system().lower() == 'windows':
        command = ['ping', '-n', str(packets), '-w', str(timeout), host_or_ip]
        # run parameters: capture output, discard error messages, do not show window
        result = subprocess.run(command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, creationflags=0x08000000)
        # 0x0800000 is a windows-only Popen flag to specify that a new process will not create a window.
        # On Python 3.7+, you can use a subprocess constant:
        #   result = subprocess.run(command, capture_output=True, creationflags=subprocess.CREATE_NO_WINDOW)
        # On windows 7+, ping returns 0 (ok) when host is not reachable; to be sure host is responding,
        # we search the text "TTL=" on the command output. If it's there, the ping really had a response.
        return result.returncode == 0 and b'TTL=' in result.stdout
    else:
        command = ['ping', '-c', str(packets), '-w', str(timeout), host_or_ip]
        # run parameters: discard output and error messages
        result = subprocess.run(command, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        return result.returncode == 0

Не стесняйтесь использовать его по своему усмотрению.

1 голос
/ 21 мая 2015

У меня было похожее требование, поэтому я реализовал его, как показано ниже. Он протестирован на 64-битной Windows и Linux.

import subprocess
def systemCommand(Command):
    Output = ""
    Error = ""     
    try:
        Output = subprocess.check_output(Command,stderr = subprocess.STDOUT,shell='True')
    except subprocess.CalledProcessError as e:
        #Invalid command raises this exception
        Error =  e.output 

    if Output:
        Stdout = Output.split("\n")
    else:
        Stdout = []
    if Error:
        Stderr = Error.split("\n")
    else:
        Stderr = []

    return (Stdout,Stderr)

#in main
Host = "ip to ping"
NoOfPackets = 2
Timeout = 5000 #in milliseconds
#Command for windows
Command = 'ping -n {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
#Command for linux 
#Command = 'ping -c {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
Stdout,Stderr = systemCommand(Command)
if Stdout:
   print("Host [{}] is reachable.".format(Host))
else:
   print("Host [{}] is unreachable.".format(Host))

Когда IP недоступен, subprocess.check_output () вызывает исключение. Дополнительную проверку можно выполнить путем извлечения информации из строки вывода «Пакеты: отправлено = 2, получено = 2, потеряно = 0 (потеря 0%)».

0 голосов
/ 26 октября 2018

Я беру заимствования из других ответов. Попытка упростить и минимизировать запросы.

import platform, os

def ping(host):
    result = os.popen(' '.join(("ping", ping.param, host))).read()
    return 'TTL=' in result

ping.param = "-n 1" if platform.system().lower() == "windows" else "-c 1"
...