在Python中,是否有一种方法可以通过ICMP来ping服务器,如果服务器响应则返回TRUE,如果没有响应则返回FALSE ?
当前回答
这个脚本适用于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
其他回答
使用python3中的套接字包:
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
在四处寻找之后,我最终编写了自己的ping模块,该模块旨在监视大量地址,是异步的,并且不使用大量系统资源。你可以在这里找到它:https://github.com/romana/multi-ping/它是Apache授权的,所以你可以在你的项目中以任何你认为合适的方式使用它。
实施我自己的方法的主要原因是其他方法的限制:
这里提到的许多解决方案都需要将exec输出到命令行实用程序。如果您需要监控大量的IP地址,这是非常低效和资源消耗的。 其他人提到了一些较老的python ping模块。我看了这些,最后,他们都有这样或那样的问题(比如没有正确设置数据包id),不能处理大量地址的ping-ing。
此函数适用于任何操作系统(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 '])。
很多答案都忽略了一点(至少在Windows中),如果ping命令收到“目标主机不可达”的回复,它将返回0(表示成功)。
下面是我的代码,它检查b' ttl ='是否在响应中,因为它只在ping到达主机时才出现。注意:此代码的大部分是基于这里的其他答案。
import platform
import subprocess
def ping(ipAddr, timeout=100):
'''
Send a ping packet to the specified host, using the system ping command.
Accepts ipAddr as string for the ping destination.
Accepts timeout in ms for the ping timeout.
Returns True if ping succeeds otherwise Returns False.
Ping succeeds if it returns 0 and the output includes b'TTL='
'''
if platform.system().lower() == 'windows':
numFlag = '-n'
else:
numFlag = '-c'
completedPing = subprocess.run(['ping', numFlag, '1', '-w', str(timeout), ipAddr],
stdout=subprocess.PIPE, # Capture standard out
stderr=subprocess.STDOUT) # Capture standard error
# print(completedPing.stdout)
return (completedPing.returncode == 0) and (b'TTL=' in completedPing.stdout)
print(ping('google.com'))
注意:这将捕获输出而不是打印输出,因此如果您希望看到ping的输出,则需要打印completedPing。返回前的Stdout。
看起来很简单,但却让我头疼。我一直得到“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
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录