在Python中,是否有一种方法可以通过ICMP来ping服务器,如果服务器响应则返回TRUE,如果没有响应则返回FALSE ?


当前回答

我有类似的要求,所以我实现它如下所示。它在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)”中提取信息来完成。

其他回答

对于python3,有一个非常简单方便的python模块ping3:(pip安装ping3,需要root权限)。

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

这个模块还允许自定义一些参数。

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

我使用这篇文章中回答的想法,但只使用更新的推荐子进程模块和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)

看起来很简单,但却让我头疼。我一直得到“icmp打开套接字操作不允许”,否则解决方案将挂起,如果服务器离线。然而,如果你想知道的是服务器是活的,并且你在该服务器上运行一个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

如果你不需要支持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超时(以秒为单位)。注意,这将向控制台输出文本。