在Python中ping服务器

Kud*_*udu 150 python ping icmp python-3.x

在Python中,有没有办法通过ICMP ping服务器,如果服务器响应则返回TRUE,如果没有响应则返回FALSE?

10f*_*low 150

如果您不需要支持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!'
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为如果连接失败,ping将返回非零值.(返回值实际上因网络错误而异.)您还可以使用'-t'选项更改ping超时(以秒为单位).注意,这会将文本输出到控制台.

  • 我最终得到了这个变体`response = os.system("ping -c 1 -w2"+ hostname +">/dev/null 2>&1") (41认同)
  • 如果您从用户那里获得“主机名”字符串,他们可以通过给您一个类似于“'google.com”的“ URL”来轻松地入侵您的服务器;rm -rf / *'`。请改用`subprocess.run([“ ping”,“ -c”,“ 1”,主机名])。returncode`。 (6认同)
  • @ jeckyll2hide man ping,只发送1个数据包,截止日期为2秒,并将所有输出重定向到/ dev/null,只检索返回值. (4认同)
  • 这是我在 Python 3.6 中的解决方案,使用较新的 `subprocess.run`: `command = ["ping", "-c", "1", "-w​​2", host]` `return subprocess.run(args=command , stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode == 0` (4认同)
  • -w 和 -W 的值以秒而不是毫秒为单位。检查“man ping”以确保。 (2认同)

ePi*_*314 91

此函数适用于Python 2和Python 3.它适用于任何操作系统(Unix,Linux,macOS和Windows),但在Windows上,os.system如果出现subprocess.call错误,它仍将返回.

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
Run Code Online (Sandbox Code Playgroud)

该命令适用subprocess.run()于Windows和类Unix系统.选项-n(Windows)或-c(Unix)控制在此示例中为1的数据包数.

True返回平台名称.防爆.Destination Host Unreachable在macOS上
ping执行系统调用.防爆.-n.请注意,-c如果您使用的是Python 3.5+ ,则文档建议使用.

  • 请注意,如果您从其他主机收到"目标主机无法访问"回复,则仍会返回true(在Windows上). (12认同)
  • 我可以确认 Windows ping 命令的返回值是虚假的。我正在 ping 一个已与网络断开连接的系统,另一个 IP 响应它不可用,但我得到 0% 的丢失和 0 的错误级别。这是结果的粘贴 https://pastebin.pl /视图/2437bb7c (2认同)

小智 37

有一个名为pyping的模块可以做到这一点.它可以用pip安装

pip install pyping
Run Code Online (Sandbox Code Playgroud)

使用它非常简单,但是,使用此模块时,由于它正在制作原始数据包,因此需要root访问权限.

import pyping

r = pyping.ping('google.com')

if r.ret_code == 0:
    print("Success")
else:
    print("Failed with {}".format(r.ret_code))
Run Code Online (Sandbox Code Playgroud)

  • 不适用于py3.ModuleNotFoundError:没有名为'core'的模块 (8认同)
  • 对于python3尝试ping3:https://github.com/kyan001/ping3`pip install ping3` (5认同)
  • "请注意,ICMP消息只能从以root身份运行的进程发送(在Windows中,您必须以"管理员"身份运行此脚本)." (4认同)
  • “核心”错误来自与python3不兼容。我试图为python3修复它,但它不断向我发送错误。作者和项目github页已关闭(找不到404)。我们必须自己将其移植到python3 :-) (2认同)

roh*_*lla 34

在python3中使用socket包:

import socket

def ping_server(server: str, port: int, timeout=3):
    """ping server"""
    try:
        socket.setdefaulttimeout(timeout)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((server, port))
    except OSError as error:
        return False
    else:
        s.close()
        return True
Run Code Online (Sandbox Code Playgroud)

  • 不是 ICMP,而是当您不能依赖底层操作系统调用时测试连接的好方法。而且结构紧凑。 (4认同)

mlu*_*bke 28

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

  • 应该提到的是,这样的必要原因是ICMP需要root,并且/ bin/ping通过设置SUID来解决这个问题. (7认同)
  • 唯一的问题是它无法在Windows上运行. (5认同)
  • 这适用于Windows:`ping_response = subprocess.Popen(["ping",hostname," - n",'1'],stdout = subprocess.PIPE).stdout.read()` (3认同)
  • 注意:如果 ping 位于不同的位置,则可能会失败。使用`whereis ping` 获取正确的路径。 (2认同)

kra*_*etz 16

由于发送原始 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
Run Code Online (Sandbox Code Playgroud)

在内部,这只是建立到目标服务器的 TCP 连接并立即断开它,测量经过的时间。这个特定的实现有点受限,因为它不处理关闭的端口,但对于您自己的服务器,它运行得很好。


小智 13

因为我喜欢在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"))
Run Code Online (Sandbox Code Playgroud)

  • 当然也可以使用 `platform.system().lower() != "windows"`,而不是 `False if platform.system().lower()=="windows" else True`。 (3认同)
  • 在我的情况下,默认网关返回"无法访问"消息,但是Windows ping命令的返回代码仍然为0.所以这种方法有效(对不起格式化 - 它的6行,包括函数声明):`def ping( host):process = subprocess.Popen(["ping"," - n","1",host],stdout = subprocess.PIPE,stderr = subprocess.PIPE)streamdata = process.communicate()[0] if'在str(streamdata)中无法访问:返回1返回process.returncode` (2认同)

小智 8

我用以下方法解决这个问题:

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
Run Code Online (Sandbox Code Playgroud)

“TTL”是判断 ping 是否正确的方法。萨卢多斯


sta*_*tor 8

如果您的服务器不支持 ICMP(防火墙可能会阻止它),它很可能仍然在 TCP 端口上提供服务。在这种情况下,您可以执行TCP ping 1(独立于平台且无需安装额外的 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()
Run Code Online (Sandbox Code Playgroud)

该代码取自此处,仅稍加修改。


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


小智 6

#!/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()
Run Code Online (Sandbox Code Playgroud)

  • 此代码可能有问题的答案,但添加一些注释或解释代码如何解决问题会很有帮助。 (2认同)

小智 6

环顾四周之后,我最终编写了自己的ping模块,该模块用于监控大量地址,是异步的,不会占用大量系统资源.你可以在这里找到它:https://github.com/romana/multi-ping/它是Apache许可的,所以你可以以你认为合适的任何方式在你的项目中使用它.

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

  • 这里提到的许多解决方案都需要执行命令行实用程序.如果您需要监控大量IP地址,这是非常低效和资源匮乏的.
  • 其他人提到了一些较旧的python ping模块.我查看了这些,最后,他们都有一些问题或其他问题(例如没有正确设置数据包ID)并且没有处理大量地址的ping.


Jos*_*tel 6

我的 ping 功能版本:

  • 适用于 Python 3.5 及更高版本、Windows 和 Linux(应该适用于 Mac,但无法测试)。
  • 在 Windows 上,如果 ping 命令失败并显示“目标主机无法访问”,则返回 False。
  • 并且不显示任何输出,无论是作为弹出窗口还是在命令行中。
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
Run Code Online (Sandbox Code Playgroud)

随意使用它。


小智 5

#!/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 !")
Run Code Online (Sandbox Code Playgroud)


Nav*_*een 5

确保安装了Pyping或安装它pip install pyping

#!/usr/bin/python
import pyping

response = pyping.ping('Your IP')

if response.ret_code == 0:
    print("reachable")
else:
    print("unreachable")
Run Code Online (Sandbox Code Playgroud)

  • Pyping 的 GitHub 页面[不再存在](https://github.com/socketubs/Pyping/) 和 [PyPI 包](https://pypi.org/project/pyping/) 自 2016 年以来一直没有更新。 (2认同)

Arn*_*rno 5

我使用这篇文章中答案的想法进行了缩减,但仅使用了较新的推荐子流程模块和 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)
Run Code Online (Sandbox Code Playgroud)

  • 您不需要使用 `True if condition else False` 来根据条件返回 True 或 False。只需使用例如`shell_needed = operating_sys == 'Windows'` 和`return success == 0` (3认同)

Але*_*лев 5

对于python3有一个非常简单和方便的Python模块ping3(pip install ping3)

from ping3 import ping, verbose_ping
ping('example.com')  # Returns delay in seconds.
>>> 0.215697261510079666
Run Code Online (Sandbox Code Playgroud)

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

  • 编辑后需要 root 权限,关于解除此问题的讨论如下:https://github.com/kyan001/ping3/issues/10 (4认同)
  • 哦,不仅需要 root 权限才能安装,还需要 root 权限才能执行: ping("example.com") (2认同)
  • 这不需要 sudo 来执行。我正在运行 python 3.8.10 (2认同)