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


当前回答

在四处寻找之后,我最终编写了自己的ping模块,该模块旨在监视大量地址,是异步的,并且不使用大量系统资源。你可以在这里找到它:https://github.com/romana/multi-ping/它是Apache授权的,所以你可以在你的项目中以任何你认为合适的方式使用它。

实施我自己的方法的主要原因是其他方法的限制:

这里提到的许多解决方案都需要将exec输出到命令行实用程序。如果您需要监控大量的IP地址,这是非常低效和资源消耗的。 其他人提到了一些较老的python ping模块。我看了这些,最后,他们都有这样或那样的问题(比如没有正确设置数据包id),不能处理大量地址的ping-ing。

其他回答

在windows或linux中Ping它们,返回一个排序的列表。这是@Ahmed Essam和@Arno回复的混合/修正。

import asyncio
import re

import platform
isWindows = platform.system()


async def ping(host):
    cmd = 'ping {} {} 1'.format(host, '-n' if isWindows else '-c')
    ping_proc = \
        await asyncio.create_subprocess_shell(cmd, stdout=asyncio.subprocess.PIPE,
                                                      stderr=asyncio.subprocess.PIPE)
    stdout, stderr = await ping_proc.communicate()
    outstr = stdout.decode()

    if ping_proc.returncode == 0:
        delay = int(re.search(r'(?:time=)([\d]*)', outstr).group(1)) if 'time=' in outstr else -1
        if delay >= 0:
            # print('{} {}ms'.format(host, delay))
            return [host, delay]

    return [host, None]


async def ping_all():
    tasks = []

    for i in range(1, 256):
        ip = "192.168.1.{}".format(i)
        task = asyncio.ensure_future(ping(ip))
        tasks.append(task)

    retList = await asyncio.gather(*tasks, return_exceptions=True)
    retList = [x for x in retList if x[1] is not None]
    retList.sort(key=lambda x: int(x[0].split('.')[-1]))

    return retList


loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
pingRet = loop.run_until_complete(ping_all())

for ip, d in pingRet:
    print('{:<16s} {}ms'.format(ip, d))
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()

WINDOWS ONLY -不敢相信没有人破解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'

样例输出

我的解决方法是:

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

这个脚本适用于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