在Python中,是否有一种方法可以通过ICMP来ping服务器,如果服务器响应则返回TRUE,如果没有响应则返回FALSE ?
当前回答
我需要一个更快的ping扫描,我不想使用任何外部库,所以我决定使用内置的asyncio来实现并发。
此代码需要python 3.7+,仅在Linux上制作和测试。它不能在Windows上工作,但我相信你可以很容易地将其更改为在Windows上工作。
我不是asyncio方面的专家,但我使用了这篇很棒的文章,用并发性加速你的Python程序,我想出了这些代码行。我试图使它尽可能简单,所以很可能您需要添加更多的代码来满足您的需求。
它不会返回true或false,我认为让它打印响应ping请求的IP会更方便。我认为这是相当快的,在近10秒内ping 255个ip。
#!/usr/bin/python3
import asyncio
async def ping(host):
"""
Prints the hosts that respond to ping request
"""
ping_process = await asyncio.create_subprocess_shell("ping -c 1 " + host + " > /dev/null 2>&1")
await ping_process.wait()
if ping_process.returncode == 0:
print(host)
return
async def ping_all():
tasks = []
for i in range(1,255):
ip = "192.168.1.{}".format(i)
task = asyncio.ensure_future(ping(ip))
tasks.append(task)
await asyncio.gather(*tasks, return_exceptions = True)
asyncio.run(ping_all())
样例输出:
192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6
请注意,IP不是按顺序排列的,因为IP在它响应时就会打印出来,所以先响应的就会先打印出来。
其他回答
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()
我需要一个更快的ping扫描,我不想使用任何外部库,所以我决定使用内置的asyncio来实现并发。
此代码需要python 3.7+,仅在Linux上制作和测试。它不能在Windows上工作,但我相信你可以很容易地将其更改为在Windows上工作。
我不是asyncio方面的专家,但我使用了这篇很棒的文章,用并发性加速你的Python程序,我想出了这些代码行。我试图使它尽可能简单,所以很可能您需要添加更多的代码来满足您的需求。
它不会返回true或false,我认为让它打印响应ping请求的IP会更方便。我认为这是相当快的,在近10秒内ping 255个ip。
#!/usr/bin/python3
import asyncio
async def ping(host):
"""
Prints the hosts that respond to ping request
"""
ping_process = await asyncio.create_subprocess_shell("ping -c 1 " + host + " > /dev/null 2>&1")
await ping_process.wait()
if ping_process.returncode == 0:
print(host)
return
async def ping_all():
tasks = []
for i in range(1,255):
ip = "192.168.1.{}".format(i)
task = asyncio.ensure_future(ping(ip))
tasks.append(task)
await asyncio.gather(*tasks, return_exceptions = True)
asyncio.run(ping_all())
样例输出:
192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6
请注意,IP不是按顺序排列的,因为IP在它响应时就会打印出来,所以先响应的就会先打印出来。
在四处寻找之后,我最终编写了自己的ping模块,该模块旨在监视大量地址,是异步的,并且不使用大量系统资源。你可以在这里找到它:https://github.com/romana/multi-ping/它是Apache授权的,所以你可以在你的项目中以任何你认为合适的方式使用它。
实施我自己的方法的主要原因是其他方法的限制:
这里提到的许多解决方案都需要将exec输出到命令行实用程序。如果您需要监控大量的IP地址,这是非常低效和资源消耗的。 其他人提到了一些较老的python ping模块。我看了这些,最后,他们都有这样或那样的问题(比如没有正确设置数据包id),不能处理大量地址的ping-ing。
如果您的服务器不支持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端口,即不传输任何数据,而是在连接后立即关闭连接。
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'
样例输出
推荐文章
- 如何在Python中进行热编码?
- 如何嵌入HTML到IPython输出?
- 在Python生成器上使用“send”函数的目的是什么?
- 是否可以将已编译的.pyc文件反编译为.py文件?
- Django模型表单对象的自动创建日期
- 在Python中包装长行
- 如何计算两个时间串之间的时间间隔
- 我如何才能找到一个Python函数的参数的数量?
- 您可以使用生成器函数来做什么?
- 将Python诗歌与Docker集成
- 提取和保存视频帧
- 使用请求包时出现SSL InsecurePlatform错误
- 如何检索Pandas数据帧中的列数?
- except:和except的区别:
- 错误:“字典更新序列元素#0的长度为1;2是必需的”