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

В Python существует ли способ выполнить ping-сервер через ICMP и вернуть TRUE, если сервер отвечает, или FALSE, если ответа нет?

Ответ 1

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

import os
hostname = "google.com" #example
response = os.system("ping -c 1 " + hostname)

#and then check the response...
if response == 0:
  print hostname, 'is up!'
else:
  print hostname, 'is down!'

Это работает, потому что ping возвращает ненулевое значение, если соединение терпит неудачу. (Возвращаемое значение фактически различается в зависимости от сетевой ошибки.) Вы также можете изменить тайм-аут ping (в секундах) с помощью опции -t. Обратите внимание, что это выведет текст на консоль.

Ответ 2

Эта функция работает в любой ОС (Unix, Linux, macOS и Windows)
Python 2 и Python 3

Редактирует:
@radato os.system был заменен на subprocess.call.
@Boris В документации рекомендуется использовать subprocess.run(), если вы используете Python 3. 5+.

import platform    # For getting the operating system name
import subprocess  # For executing a shell command

def ping(host):
    """
    Returns True if host (str) responds to a ping request.
    Remember that a host may not respond to a ping (ICMP) request even if the host name is valid.
    """

    # Option for the number of packets as a function of
    param = '-n' if platform.system().lower()=='windows' else '-c'

    # Building the command. Ex: "ping -c 1 google.com"
    command = ['ping', param, '1', host]

    return subprocess.call(command) == 0

Обратите внимание, что, согласно @ikrase в Windows, эта функция по-прежнему будет возвращать True, если вы получите ошибку Destination Host Unreachable.

Объяснение

Команда ping используется как в Windows, так и в Unix-подобных системах.
Опция -n (Windows) или -c (Unix) контролирует количество пакетов, которое в этом примере было установлено на 1.

platform.system() возвращает имя платформы. Ex. 'Darwin' в macOS.
subprocess.call() выполняет системный вызов. Ex. subprocess.call(['ls','-l']).

Ответ 3

Существует модуль, называемый pyping, который может сделать это. Может быть установлен с помощью pip

pip install pyping

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

import pyping

r = pyping.ping('google.com')

if r.ret_code == 0:
    print("Success")
else:
    print("Failed with {}".format(r.ret_code))

Ответ 4

import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()

Ответ 5

Поскольку мне нравится, когда моя программа Python универсальна для версий 2.7 и 3.x, а также на платформе Linux, Mac OS и Windows, мне пришлось изменить существующие примеры.

# shebang does not work over all platforms
# ping.py  2016-02-25 Rudolf
# subprocess.call() is preferred to os.system()
# works under Python 2.7 and 3.4
# works under Linux, Mac OS, Windows

def ping(host):
    """
    Returns True if host responds to a ping request
    """
    import subprocess, platform

    # Ping parameters as function of OS
    ping_str = "-n 1" if  platform.system().lower()=="windows" else "-c 1"
    args = "ping " + " " + ping_str + " " + host
    need_sh = False if  platform.system().lower()=="windows" else True

    # Ping
    return subprocess.call(args, shell=need_sh) == 0

# test call
print(ping("192.168.17.142"))

Ответ 6

Чистая пинговая служба Python как класс Linux или Windows, который использует потоки:

https://github.com/duanev/ping-python

Ответ 7

#!/usr/bin/python3

import subprocess as sp

def ipcheck():
    status,result = sp.getstatusoutput("ping -c1 -w2 " + str(pop))
    if status == 0:
        print("System " + str(pop) + " is UP !")
    else:
        print("System " + str(pop) + " is DOWN !")


pop = input("Enter the ip address: ")
ipcheck()

Ответ 8

После осмотра я написал свой собственный модуль ping, который предназначен для мониторинга большого количества адресов, является асинхронным и не использует много системных ресурсов. Вы можете найти его здесь: https://github.com/romana/multi-ping/ Он лицензирован Apache, так что вы можете использовать его в своем проекте любым удобным для вас способом.

Основными причинами реализации моих собственных являются ограничения других подходов:

  • Многие из упомянутых здесь решений требуют exec для утилиты командной строки. Это довольно неэффективно и требует много ресурсов, если вам нужно отслеживать большое количество IP-адресов.
  • Другие упоминают некоторые старые модули ping для Python. Я посмотрел на них, и, в конце концов, у них у всех была та или иная проблема (например, неправильная установка идентификаторов пакетов), и они не обрабатывали пинг большого количества адресов.

Ответ 9

Убедитесь, что установлен пирс, или установите его pip install pyping

#!/usr/bin/python
import pyping

response = pyping.ping('Your IP')

if response.ret_code == 0:
    print("reachable")
else:
    print("unreachable")

Ответ 10

Мое сокращение - использование идей из ответов в этом посте, но только с использованием более нового рекомендуемого модуля подпроцесса и python3:

import subprocess
import platform

operating_sys = platform.system()
nas = '192.168.0.10'

def ping(ip):
    # ping_command = ['ping', ip, '-n', '1'] instead of ping_command = ['ping', ip, '-n 1'] for Windows
    ping_command = ['ping', ip, '-n', '1'] if operating_sys == 'Windows' else ['ping', ip, '-c 1']
    shell_needed = True if operating_sys == 'Windows' else False

    ping_output = subprocess.run(ping_command,shell=shell_needed,stdout=subprocess.PIPE)
    success = ping_output.returncode
    return True if success == 0 else False

out = ping(nas)
print(out)

Ответ 11

Я разрешаю это с помощью:

def ping(self, host):
    res = False

    ping_param = "-n 1" if system_name().lower() == "windows" else "-c 1"

    resultado = os.popen("ping " + ping_param + " " + host).read()

    if "TTL=" in resultado:
        res = True
    return res

"TTL" - это способ узнать, правильно ли выполняется пинг. Салудос

Ответ 12

Для python3 существует очень простой и удобный модуль python ping3: (pip install ping3).

from ping3 import ping, verbose_ping
ping('example.com')  # Returns delay in seconds.
>>> 0.215697261510079666

Этот модуль также позволяет настраивать некоторые параметры.

Ответ 13

Программный 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-соединение с целевым сервером и немедленно сбрасывает его, измеряя прошедшее время. Эта конкретная реализация немного ограничена в том, что она не обрабатывает закрытые порты, но для ваших собственных серверов она работает довольно хорошо.

Ответ 14

#!/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 !")

Ответ 15

Этот script работает в Windows и должен работать на других ОС: Он работает на Windows, Debian и macosx, нужен тест на солярии.

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

Ответ 16

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

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

import pyping

response = pyping.send('Your IP')

if response['ret_code'] == 0:
    print("reachable")
else:
    print("unreachable")

Ответ 17

Используя 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 " можно игнорировать!

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

Ответ 18

Моя версия функции 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 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

Не стесняйтесь использовать его, как вы будете.

Ответ 19

У меня было подобное требование, поэтому я реализовал его, как показано ниже. Он протестирован на 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%)".

Ответ 20

Здесь решение с использованием модуля subprocess Python и инструмента ping CLI, предоставляемого базовой ОС. Проверено на Windows и Linux. Поддержка установки таймаута сети. Не нужны права root (по крайней мере, в 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

Ответ 21

Кажется довольно простым, но дал мне припадки. Я продолжал получать "icmp open socket operation not allowed", иначе решения зависают, если сервер не работает. Если, однако, то, что вы хотите знать, это то, что сервер жив, и вы используете веб-сервер на этом сервере, тогда завиток выполнит эту работу. Если у вас есть ssh и сертификаты, то ssh и простая команда будут достаточными. Вот код:

from easyprocess import EasyProcess # as root: pip install EasyProcess
def ping(ip):
    ping="ssh %s date;exit"%(ip) # test ssh alive or
    ping="curl -IL %s"%(ip)      # test if http alive
    response=len(EasyProcess(ping).call(timeout=2).stdout)
    return response #integer 0 if no response in 2 seconds

Ответ 22

Использовать его для тестирования на python 2.7 и отлично работает, он возвращает время ping в миллисекундах, если успех и возврат False при сбое.

import platform,subproccess,re
def Ping(hostname,timeout):
    if platform.system() == "Windows":
        command="ping "+hostname+" -n 1 -w "+str(timeout*1000)
    else:
        command="ping -i "+str(timeout)+" -c 1 " + hostname
    proccess = subprocess.Popen(command, stdout=subprocess.PIPE)
    matches=re.match('.*time=([0-9]+)ms.*', proccess.stdout.read(),re.DOTALL)
    if matches:
        return matches.group(1)
    else: 
        return False

Ответ 23

Одна вещь, которую пропускают многие ответы, заключается в том, что (по крайней мере, в Windows) команда ping возвращает 0 (что указывает на успешность), если она получает ответ "Узел назначения недоступен".

Вот мой код, который проверяет, присутствует ли b'TTL=' в ответе, так как он присутствует, только когда пинг достиг хоста. Примечание: большая часть этого кода основана на других ответах здесь.

import platform
import subprocess

def ping(ipAddr, timeout=100):
    '''
    Send a ping packet to the specified host, using the system ping command.
    Accepts ipAddr as string for the ping destination.
    Accepts timeout in ms for the ping timeout.
    Returns True if ping succeeds otherwise Returns False.
        Ping succeeds if it returns 0 and the output includes b'TTL='
    '''
    if platform.system().lower() == 'windows':
        numFlag = '-n'
    else:
        numFlag = '-c'
    completedPing = subprocess.run(['ping', numFlag, '1', '-w', str(timeout), ipAddr],
                                   stdout=subprocess.PIPE,    # Capture standard out
                                   stderr=subprocess.STDOUT)  # Capture standard error
    # print(completedPing.stdout)
    return (completedPing.returncode == 0) and (b'TTL=' in completedPing.stdout)

print(ping('google.com'))

Примечание. Это захватывает вывод вместо его печати, поэтому, если вы хотите увидеть вывод команды ping, вам нужно будет напечатать completedPing.stdout перед возвратом.

Ответ 24

ТОЛЬКО для WINDOWS - Не могу поверить, что никто не взломал Win32_PingStatus Используя простой WMI-запрос, мы возвращаем объект, полный действительно подробной информации, бесплатно

import wmi


# new WMI object
c = wmi.WMI()

# here is where the ping actually is triggered
x = c.Win32_PingStatus(Address='google.com')

# how big is this thing? - 1 element
print 'length x: ' ,len(x)


#lets look at the object 'WMI Object:\n'
print x


#print out the whole returned object
# only x[0] element has values in it
print '\nPrint Whole Object - can directly reference the field names:\n'
for i in x:
    print i



#just a single field in the object - Method 1
print 'Method 1 ( i is actually x[0] ) :'
for i in x:
    print 'Response:\t', i.ResponseTime, 'ms'
    print 'TTL:\t', i.TimeToLive


#or better yet directly access the field you want
print '\npinged ', x[0].ProtocolAddress, ' and got reply in ', x[0].ResponseTime, 'ms'

образец вывода

Ответ 25

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

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"

Ответ 26

Вы можете использовать исключение TimeoutExpired модуля подпроцесса, чтобы перехватывать таймауты ping (то, что другие ответы не использовали.) Обратите внимание, что это решение работает только в Linux.

def ping(host, timeout=3):
    """
    Send a ping (ICMP) request to a remote host.

    The command is set to ''ping -c 1 -W 1 <host>'', which sends exactly 1 ping
    packet, and waits for 1 second before terminating.

    Args:
        host (str): Hostname or IP address.
        timeout (int): Ping command timeout (in seconds).

    Returns:
        bool: The ping response. ''True'' if the host responds to a ping request 
            within the specified timeout period. ''False'' otherwise.

    Note:
        A host may not respond to a ping (ICMP) request even if the host name is 
        valid because of firewall rules.
    """
    # Building the command. Ex: "ping -c 1 google.com"
    command = ['ping', host, '-W', '1', '-c', '1']

    try:
        subprocess.run(command, timeout=timeout, check=True)
        return True
    except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
        #log.warning("Failed to ping host: %s with timeout: %d", host, timeout)
        return False

Ответ 27

  1 #!/usr/bin/python
  2
  3 import os
  4 import sys
  5 import time
  6
  7 os.system("clear")
  8 home_network = "172.16.23."
  9 mine = []
 10
 11 for i in range(1, 256):
 12         z =  home_network + str(i)
 13         result = os.system("ping -c 1 "+ str(z))
 14         os.system("clear")
 15         if result == 0:
 16                 mine.append(z)
 17
 18 for j in mine:
 19         print "host ", j ," is up"

Простой, который я только что приготовил за минуту. Использование icmplib требует корневых привилегий, ниже работает очень хорошо! НТН