在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超时(以秒为单位)。注意,这将向控制台输出文本。

其他回答

看起来很简单,但却让我头疼。我一直得到“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

此函数适用于任何操作系统(Unix、Linux、macOS和Windows) Python 2和Python 3

编辑: @radato os。System被subprocess.call取代。这避免了在没有验证主机名字符串的情况下shell注入漏洞。

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。

解释

该命令在Windows和类unix系统中都是ping。 选项-n (Windows)或-c (Unix)控制包的数量,在本例中设置为1。

platform.system()返回平台名称。前女友。macOS上的“达尔文”。 Subprocess.call()执行一个系统调用。例如subprocess.call ([' ls ', ' - l '])。

编程ICMP ping很复杂,因为发送原始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连接,并立即丢弃它,测量所消耗的时间。这个特殊的实现有点局限,因为它不能处理封闭的端口,但对于您自己的服务器来说,它工作得很好。

有一个名为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()