我有以下脚本:
#!/usr/bin/env python3
import os
i = 1
while i != 255:
Test = os.system("ping -c 1 10.0.0." + str(i) + " > /dev/null")
if Test == 0:
print("Host: 10.0.0." + str(i) + " is up!");
i = i + 1
else:
i = i + 1
这是一个类似 NMap 的 python 脚本,我很无聊,决定制作它。
无论如何,当我运行它时,它非常慢,但是当我按住 CTRL + C 时,它会快得多......而且它有效!
有没有办法可以让这个脚本变得更快?
最佳答案
默认情况下,ping 会等待 10 秒数据包到达。由于许多地址不会被使用,或者拥有这些地址的计算机不会响应 ICMP echo (ping) 数据包,因此您最多需要等待 2550 秒,如果某些地址引发响应,则等待时间会短一点。
当您键入 Ctrl+C 时,您会发送一个 SIGTERM
信号,该信号会中止等待。如果您在收到 ICMP 回显响应之前中止 ping,您将得到不正确的结果。由于本地网络速度相当快,因此您不太可能遇到这种情况。
为了加快速度,您可以通过两种方式修改您的方法:
- 在没有回应时尽早放弃。传入
-W
参数。例如,通过运行ping -c 1 -W 1 ...
,ping 将只等待一秒钟,因此整个程序将花费大约 250 秒。 - 并行运行 ping。您可以手动执行此操作,通常使用
Pool
线程/进程数(或每个 ping 仅一个线程/进程)。请注意,您的操作系统可能会强制限制每秒 ping 的数量。例如,如果您将超时设置为 10 秒并设法同时运行所有 ping,则您的程序将只需要 10 秒。
使用池的正确代码可能如下所示
import multiprocessing
import subprocess
TIMEOUT = 5 # in seconds
CONCURRENCY = 100 # how many pings in parallel?
def ping(ip):
""" Returns true iff the host is reachable. """
# print('ping %s' % ip) # uncomment to see progress
ret = subprocess.call(
['ping', '-W', str(TIMEOUT), '-c', '1', ip],
stdout=subprocess.DEVNULL)
if ret == 0:
print('%s is reachable' % ip)
ips = ('10.0.0.%d' % i for i in range(1, 255))
with multiprocessing.Pool(CONCURRENCY) as p:
p.map(ping, ips)
如果您不想闲逛,您可能还想使用一个程序来代替并行运行的 ping。任何端口扫描仪(例如 nmap )都应该可以正常工作。
关于python - os.system ("ping")调用非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42287398/