在Python中,是否有一种方法可以通过ICMP来ping服务器,如果服务器响应则返回TRUE,如果没有响应则返回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需要根privs下面的工作非常好! HTH

其他回答

如果您的服务器不支持ICMP(防火墙可能会阻止它),它很可能仍然在TCP端口上提供服务。在这种情况下,你可以像这样执行TCP ping1(平台独立,无需安装额外的python模块):

import socket

def isReachable(ipOrName, port, timeout=2):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(timeout)
    try:
        s.connect((ipOrName, int(port)))
        s.shutdown(socket.SHUT_RDWR)
        return True
    except:
        return False
    finally:
        s.close()

代码从这里开始只做了轻微的修改。


1 TCP ping并不真正存在,因为ping是在ISO/OSI第三层用ICMP执行的。TCP ping在ISO/OSI第4层执行。它只是试图以最基本的方式连接到TCP端口,即不传输任何数据,而是在连接后立即关闭连接。

我自己的方法结合了上面的几个答案:


def ping(host, show_log=False, package_count=1):
    ping.param = "-n" if platform.system().lower() == 'windows' else "-c"
    result = subprocess.run(['ping', ping.param, str(package_count), host],
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT)
    output = result.stdout
    if show_log:
        print('return code: ', result.returncode)
        print(output.decode("utf-8"))
    return result.returncode == 0 and (b'TTL=' in output or b'ttl=' in output)

在OSX Monterey上测试。

下面是一个使用Python的子进程模块和底层操作系统提供的ping CLI工具的解决方案。在Windows和Linux上测试。支持设置网络超时。不需要根权限(至少在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
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()

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