En Python, existe-t-il un moyen d'envoyer un ping à un serveur via ICMP et de renvoyer TRUE si le serveur répond ou FALSE s'il n'y a pas de réponse?
Si vous n'avez pas besoin de prendre en charge Windows, voici une manière très concise de le faire:
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!'
Cela fonctionne car ping renvoie une valeur non nulle si la connexion échoue. (La valeur de retour varie en fonction de l'erreur réseau.) Vous pouvez également modifier le délai d'attente du ping (en secondes) à l'aide de l'option '-t'. Notez que cela affichera du texte sur la console.
Cette fonction fonctionne sur Python 2 et Python 3. Elle fonctionne sur n’importe quel système d’exploitation (Unix, Linux, macOS et Windows), mais sous Windows, elle retournera quand même True
si vous obtenez une erreur Destination Host Unreachable
.
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.
"""
# Ping command count option as function of OS
param = '-n' if platform.system()=='Windows' else '-c'
# Building the command. Ex: "ping -c 1 google.com"
command = ['ping', param, '1', Host]
return system.call(command) == 0
La commande est ping
dans les systèmes Windows et Unix-like . L'option -n (Windows) ou -c (Unix) contrôle le nombre de paquets qui, dans cet exemple, est 1.
platform.system()
renvoie le nom de la plate-forme. Ex. 'Darwin'
sur macOSsubprocess.call()
effectue un appel système. Ex. subprocess.call(['ls','-l'])
. Notez que la documentation recommande d’utiliser subprocess.run()
si vous utilisez Python 3.5+.
Il existe un module appelé pyping qui peut le faire. Il peut être installé avec pip
pip install pyping
C'est assez simple à utiliser, cependant, lorsque vous utilisez ce module, vous avez besoin d'un accès root, car il crée des paquets bruts sous le capot.
import pyping
r = pyping.ping('google.com')
if r.ret_code == 0:
print("Success")
else:
print("Failed with {}".format(r.ret_code))
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()
Parce que j'aime avoir mon programme Python universel sur les versions 2.7 et 3.x et sur les plateformes Linux, Mac OS et Windows, j'ai dû modifier les exemples existants.
# 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"))
Assurez-vous que Pyping est installé ou installez-le pip install Pyping
#!/usr/bin/python
import pyping
response = pyping.ping('Your IP')
if response.ret_code == 0:
print("reachable")
else:
print("unreachable")
Après avoir regardé autour de moi, j'ai fini par écrire mon propre module ping, conçu pour surveiller un grand nombre d'adresses, il est asynchrone et n'utilise pas beaucoup de ressources système. Vous pouvez le trouver ici: https://github.com/romana/multi-ping/ Il est sous licence Apache, vous pouvez donc l'utiliser dans votre projet comme bon vous semble.
Les principales raisons pour mettre en œuvre la mienne sont les restrictions des autres approches:
#!/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()
Utilisation de Multi-ping (pip install multiPing
) J'ai créé ce code simple (simplement copier et coller si vous voulez!):
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
Utilisation:
#Getting the latency average (in seconds) of Host '192.168.0.123' using 10 samples
ping('192.168.0.123',10)
Si vous voulez un seul échantillon, le second paramètre "10
" peut être ignoré!
J'espère que ça aide!
#!/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 !")
Le ping ICMP par programmation est compliqué à cause des privilèges élevés requis pour envoyer des paquets ICMP bruts, et appeler ping
binary est moche. Pour la surveillance du serveur, vous pouvez obtenir le même résultat en utilisant une technique appelée 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
En interne, cela établit simplement une connexion TCP au serveur cible et l’interrompt immédiatement, le temps de mesure étant écoulé. Cette implémentation particulière est un peu limitée car elle ne gère pas les ports fermés, mais elle fonctionne plutôt bien pour vos propres serveurs.
J'ai fini par trouver cette question concernant un scénario similaire. J'ai essayé de pyper mais l'exemple donné par Naveen ne fonctionnait pas pour moi sous Windows sous Python 2.7.
Un exemple qui a fonctionné pour moi est:
import pyping
response = pyping.send('Your IP')
if response['ret_code'] == 0:
print("reachable")
else:
print("unreachable")
Ma réduction en utilisant des idées de réponses dans ce post mais en utilisant uniquement le module de sous-processus recommandé plus récent et 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)
Je résous ceci avec:
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" est le moyen de savoir si le ping est correct . Saludos
Ce script fonctionne sous Windows et devrait fonctionner sous d’autres systèmes d’exploitation: Il fonctionne sous Windows, Debian et macosx, et nécessite un test sur 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
J'ai aimé ping3 https://github.com/kyan001/ping3 Très simple et pratique!
from ping3 import ping, verbose_ping
ping('example.com') # Returns delay in seconds.
>>>0.215697261510079666
J'avais des exigences similaires, je l'ai donc implémenté comme indiqué ci-dessous. Il est testé sur Windows 64 bits et 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))
Lorsque IP n'est pas accessible, subprocess.check_output () déclenche une exception. Une vérification supplémentaire peut être effectuée en extrayant des informations de la ligne de sortie 'Paquets: envoyés = 2, reçus = 2, perdus = 0 (perte 0%)'.
Voici une solution utilisant le module subprocess
de Python et l'outil CLI ping
fourni par le système d'exploitation sous-jacent. Testé sous Windows et Linux. Prise en charge de la configuration d'un délai d'attente du réseau. N'a pas besoin de privilèges root (au moins sur Windows et 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
Utilisez ceci, il est testé sur Python 2.7 et fonctionne correctement. Il renvoie le temps de ping en millisecondes en cas de succès et renvoie False en cas d'échec.
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
Vous pouvez utiliser l'exception TimeoutExpired
du module de sous-processus pour intercepter les délais d'attente de ping (quelque chose que les autres réponses n'ont pas exploité.) Notez que cette solution ne fonctionne que sous 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
Cela semble assez simple, mais m'a donné des crises. Je continuais à obtenir "opération de socket ouvert icmp non autorisée", sinon les solutions ne fonctionneraient pas si le serveur était hors ligne. Si, toutefois, vous voulez savoir que le serveur est actif et que vous utilisez un serveur Web sur ce serveur, alors curl fera le travail. Si vous avez ssh et des certificats, alors ssh et une commande simple suffiront. Voici le 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
WINDOWS UNIQUEMENT - Vous ne pouvez pas croire que personne ne soit craqué ouvrez Win32_PingStatus En utilisant une simple requête WMI, nous renvoyons gratuitement un objet contenant des informations vraiment détaillées
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'
Ma prise empruntant d'autres réponses. Essayez de simplifier et de minimiser les requêtes.
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"
Une chose que beaucoup de réponses manquent, c'est que (du moins sous Windows) la commande ping
renvoie 0 (indiquant le succès) si elle reçoit la réponse "Hôte de destination inaccessible".
Voici mon code qui vérifie si b'TTL='
est dans la réponse, puisqu'il n'est présent que lorsque le ping a atteint l'hôte. Remarque: La plupart de ce code est basé sur les autres réponses ici.
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'))
Remarque: Ceci capture la sortie au lieu de l’imprimer. Par conséquent, si vous souhaitez voir la sortie de ping
, vous devez imprimer completedPing.stdout
avant de renvoyer.
Ma version d'une fonction 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
N'hésitez pas à l'utiliser comme vous voulez.