it-swarm.com.de

Ping-Server in Python

Gibt es in Python eine Möglichkeit, einen Server über ICMP anzufordern und WAHR zurückzugeben, wenn der Server antwortet, oder FALSE, wenn keine Antwort vorliegt?

121
Kudu

Wenn Sie Windows nicht unterstützen müssen, können Sie dies ganz einfach tun:

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!'

Dies funktioniert, weil Ping einen Wert ungleich Null zurückgibt, wenn die Verbindung fehlschlägt. (Der Rückgabewert hängt vom Netzwerkfehler ab.) Sie können das Ping-Timeout (in Sekunden) auch mit der Option '-t' ändern. Beachten Sie, dass hierdurch Text an die Konsole ausgegeben wird.

124
10flow

Diese Funktion funktioniert unter allen Betriebssystemen (Unix, Linux, macOS und Windows)
Python 2 und Python 3

EDITS:
By @ radatoos.system Wurde durch subprocess.call Ersetzt.
Von @ Boris In der Dokumentation wird empfohlen, subprocess.run() zu verwenden, wenn Sie Python 3.5+ verwenden .

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

Beachten Sie, dass diese Funktion laut @ikrase unter Windows immer noch True zurückgibt, wenn Sie den Fehler Destination Host Unreachable Erhalten.

Erklärung

Der Befehl lautet auf Windows- und Unix-ähnlichen Systemen ping.
Die Option -n (Windows) oder -c (Unix) steuert die Anzahl der Pakete, die in diesem Beispiel auf 1 gesetzt wurden.

platform.system() gibt den Plattformnamen zurück. Ex. 'Darwin' Unter macOS.
subprocess.call() führt einen Systemaufruf durch. Ex. subprocess.call(['ls','-l']).

85
ePi272314

Es gibt ein Modul namens pyping , das dies tun kann. Es kann mit pip installiert werden 

pip install pyping

Es ist ziemlich einfach zu benutzen, aber wenn Sie dieses Modul verwenden, benötigen Sie Root-Zugriff, da es rohe Pakete unter der Haube erzeugt. 

import pyping

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

if r.ret_code == 0:
    print("Success")
else:
    print("Failed with {}".format(r.ret_code))
30
Stephen Cochran
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()
26
mluebke

Da ich mein Python-Programm unter Version 2.7 und 3.x sowie auf der Plattform Linux, Mac OS und Windows als universell einsetzen möchte, musste ich die vorhandenen Beispiele ändern.

# 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"))
11
Rudolf

Stellen Sie sicher, dass das Pyping installiert ist, oder installieren Sie es. Pip install pyping

#!/usr/bin/python
import pyping

response = pyping.ping('Your IP')

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

Nachdem ich mich umgesehen hatte, schrieb ich schließlich mein eigenes Ping-Modul, das eine große Anzahl von Adressen überwachen soll, asynchron ist und nicht viel Systemressourcen benötigt. Sie finden es hier: https://github.com/romana/multi-ping/ Da Apache lizenziert ist, können Sie es in Ihrem Projekt beliebig verwenden.

Die Hauptgründe für die Implementierung meiner eigenen sind die Einschränkungen der anderen Ansätze:

  • Viele der hier genannten Lösungen erfordern einen Exec-Befehl an ein Befehlszeilendienstprogramm. Dies ist ziemlich ineffizient und ressourcenhungrig, wenn Sie eine große Anzahl von IP-Adressen überwachen müssen.
  • Andere erwähnen einige ältere Python-Ping-Module. Ich habe mir diese angesehen und am Ende hatten sie alle ein Problem oder das andere (z. B. Paket-IDs nicht richtig eingestellt) und erledigten das Pinging einer großen Anzahl von Adressen nicht.
5
Juergen Brendel
#!/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()
5
Udayendu

Mit Multi-ping (pip install multiPing) habe ich diesen einfachen Code erstellt (einfach kopieren und einfügen, wenn Sie wollen!):

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

Verwendungszweck:

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

Wenn Sie ein einzelnes Sample wünschen, kann der zweite Parameter "10" ignoriert werden!

Ich hoffe es hilft!

3
Geraldo Neto
#!/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 !")
2
Udayendu

Programmatisches ICMP-Ping ist aufgrund der erhöhten Berechtigungen, die zum Senden von unformatierten ICMP-Paketen erforderlich sind, kompliziert und der Aufruf von ping binary ist unschön. Für die Serverüberwachung können Sie mit einer Technik namens TCP ping dasselbe Ergebnis erzielen.

# 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

Intern wird einfach eine TCP - Verbindung zum Zielserver hergestellt und sofort abgebrochen, wobei die abgelaufene Zeit gemessen wird. Diese spezielle Implementierung ist etwas eingeschränkt, da sie keine geschlossenen Ports beherrscht, aber für Ihre eigenen Server funktioniert sie ziemlich gut.

2
kravietz

Ich fand diese Frage zu einem ähnlichen Szenario. Ich habe das Pyping ausprobiert, aber das von Naveen gegebene Beispiel funktionierte für mich unter Python 2.7 nicht. 

Ein Beispiel, das für mich funktioniert hat, ist:

import pyping

response = pyping.send('Your IP')

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

Meine Reduktion mit Ideen aus den Antworten in diesem Beitrag, aber nur mit dem neueren empfohlenen Unterprozess-Modul und Python3:

import subprocess
import platform

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

def ping(ip):

    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)
2
ArnoVR

Ich löse das mit:

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" ist der Weg zu wissen, ob der Ping korrekt ist . Saludos 

2
user3620655

Dieses Skript funktioniert unter Windows und sollte unter anderen Betriebssystemen ausgeführt werden: Es funktioniert unter Windows, Debian und Macosx und benötigt einen Test unter 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
Matthew

Ich mochte ping3 https://github.com/kyan001/ping3 Sehr einfach und bequem!

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

Ich hatte eine ähnliche Anforderung, also habe ich es implementiert, wie unten gezeigt. Es wurde unter Windows 64 Bit und Linux getestet.

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))

Wenn IP nicht erreichbar ist, löst subprocess.check_output () eine Ausnahme aus. Eine zusätzliche Überprüfung kann durch Extrahieren von Informationen aus der Ausgabezeile 'Pakete: Gesendet = 2, Erhalten = 2, Verlust = 0 (0% Verlust)' durchgeführt werden.

1
Luminos

Hier ist eine Lösung, die das Modul subprocess von Python und das CLI-Tool ping des zugrunde liegenden Betriebssystems verwendet. Getestet unter Windows und Linux. Unterstützung beim Einstellen eines Netzwerk-Timeouts Benötigt keine root-Rechte (zumindest unter Windows und 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
Epoc

Verwenden Sie diese Funktion, die auf Python 2.7 getestet wurde, und funktioniert einwandfrei. Sie gibt die Ping-Zeit in Millisekunden zurück, wenn der Fehler erfolgreich ist, und gibt False zurück.

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
0
MSS

Sie können die TimeoutExpired -Ausnahme des Unterprozessmoduls verwenden, um Ping-Zeitüberschreitungen abzufangen (etwas, das die anderen Antworten nicht genutzt haben.) Beachten Sie, dass diese Lösung nur unter Linux funktioniert.

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
0
teraflik

Scheint simpel genug, hat mir aber gepasst. Ich erhielt ständig "icmp open socket operation unzulässig" oder die Lösungen würden auflegen, wenn der Server offline war. Wenn Sie jedoch wissen möchten, dass der Server aktiv ist und Sie einen Webserver auf diesem Server ausführen, erledigt curl die Aufgabe. Wenn Sie ssh und Zertifikate haben, genügt ssh und ein einfacher Befehl. Hier ist der Code:

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
0
user2099484

NUR WINDOWS - Ich kann nicht glauben, dass niemand Win32_PingStatus .__ geöffnet hat. Mit einer einfachen WMI-Abfrage geben wir ein Objekt mit wirklich detaillierten Informationen kostenlos zurück 

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'

Beispielausgabe

0
Aimondy

Ich nehme andere Antworten an. Versuchen Sie, Abfragen zu vereinfachen und zu minimieren.

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"
0
misantroop

Eine Menge Antworten, die viele Antworten vermissen, ist (zumindest in Windows), dass der Befehl ping 0 (Erfolgsmeldung) zurückgibt, wenn er die Antwort "Destination Host Unreachable" erhält.

Hier ist mein Code, der prüft, ob b'TTL=' in der Antwort enthalten ist, da dies nur vorhanden ist, wenn der Ping den Host erreicht hat. Hinweis: Der größte Teil dieses Codes basiert auf den anderen Antworten.

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'))

Hinweis: Dadurch wird die Ausgabe erfasst, anstatt sie zu drucken. Wenn Sie also die Ausgabe von ping anzeigen möchten, müssen Sie completedPing.stdout drucken, bevor Sie zurückkehren.

0
Brent Robertson

Meine Version einer Ping-Funktion:

  • Funktioniert unter Python 3.5 und höher, unter Windows und Linux (sollte unter Mac funktionieren, kann aber nicht getestet werden).
  • Gibt unter Windows "False" zurück, wenn der Ping-Befehl mit "Destination Host Unreachable" fehlschlägt.
  • Und zeigt keine Ausgabe an, weder als Popup-Fenster noch in der Befehlszeile.
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

Fühlen Sie sich frei, es zu benutzen, wie Sie wollen.