在Python中,有没有办法通过ICMP ping服务器,如果服务器响应则返回TRUE,如果没有响应则返回FALSE?
如果您不需要支持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将返回非零值。 (返回值实际上因网络错误而异。)您还可以使用'-t'选项更改ping超时(以秒为单位)。注意,这会将文本输出到控制台。
我解决这个问题:
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”是了解ping是否正确的方法。 Saludos
#!/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 !")
我最终找到了关于类似情况的这个问题。我尝试了pyping,但是Naveen给出的例子在Python 2.7下的Windows中并不适用。
一个对我有用的例子是:
import pyping
response = pyping.send('Your IP')
if response['ret_code'] == 0:
print("reachable")
else:
print("unreachable")
由于发送原始ICMP数据包所需的特权提升,编程ICMP ping很复杂,并且调用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连接并立即丢弃它,测量经过的时间。这个特定的实现有点受限制,因为它不处理关闭的端口,但对于您自己的服务器,它工作得很好。
使用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
”!
希望能帮助到你!
我有类似的要求所以我实现它如下所示。它在Windows 64位和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()会引发异常。可以通过从输出行'Packets:Sent = 2,Received = 2,Lost = 0(0%loss)'中提取信息来完成额外验证。
这个脚本适用于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
我喜欢ping3 https://github.com/kyan001/ping3非常简单方便!
from ping3 import ping, verbose_ping
ping('example.com') # Returns delay in seconds.
>>>0.215697261510079666
这是使用Python的subprocess
模块和底层操作系统提供的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
我的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
随意使用它。
此功能适用于任何操作系统(Unix,Linux,macOS和Windows) Python 2和Python 3
EDITS:
由@radato os.system
被subprocess.call
取代。
作者:@Boris如果您使用的是Python 3.5+,文档建议使用subprocess.run()
。
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
请注意,根据Windows上的@ikrase,如果出现True
错误,此函数仍会返回Destination Host Unreachable
。
说明
该命令在Windows和类Unix系统中都是ping
。
选项-n
(Windows)或-c
(Unix)控制在此示例中设置为1的数据包数。
platform.system()
返回平台名称。防爆。 'Darwin'
在macOS上。
subprocess.call()
执行系统调用。防爆。 subprocess.call(['ls','-l'])
。
看起来很简单,但给了我适合。我不断得到“不允许icmp open socket操作”,否则如果服务器脱机,解决方案就会挂断。但是,如果您想知道的是服务器处于活动状态并且您正在该服务器上运行Web服务器,那么curl将完成这项工作。如果你有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
使用它在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
许多答案错过的一件事是(至少在Windows中)ping
命令如果收到“目标主机无法访问”的回复,则返回0(表示成功)。
这是我的代码,用于检查b'TTL='
是否在响应中,因为只有在ping到达主机时才会出现。注意:此代码的大部分内容基于此处的其他答案。
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
。
仅限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'
我借鉴其他答案。尝试简化和最小化查询。
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"
您可以使用子进程模块的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
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需要root privs下面的工作非常好! HTH
有一个名为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))
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()
因为我喜欢在2.7和3.x版本以及平台Linux,Mac OS和Windows上使用Python程序,所以我不得不修改现有示例。
# 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"))
#!/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()
确保安装了Pyping或安装它pip install pyping
#!/usr/bin/python
import pyping
response = pyping.ping('Your IP')
if response.ret_code == 0:
print("reachable")
else:
print("unreachable")
环顾四周之后,我最终编写了自己的ping模块,该模块用于监控大量地址,是异步的,不会占用大量系统资源。你可以在这里找到它:https://github.com/romana/multi-ping/它是Apache许可的,所以你可以以你认为合适的任何方式在你的项目中使用它。
实现我自己的主要原因是其他方法的限制:
我使用新帖推荐的子进程模块和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)