os.system("ping") 调用很慢

os.system("ping") call very slow

我有以下脚本:

#!/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 等待 10s 等待数据包到达。由于许多地址不会被使用,或者拥有这些地址的计算机不会响应 ICMP 回显(ping)数据包,您将等待最多 2550 秒,如果某些地址引发响应,则可能会少一点。

当您键入 Ctrl+C 时,您会发送一个 SIGTERM 信号,这会中止等待。如果您在 ping 收到 ICMP 回显响应之前中止它,您将得到不正确的结果。由于本地网络非常快,您不太可能遇到这种情况。

要加快速度,您可以通过两种方式修改您的方法:

  1. 没有回应就早点放弃。传入 -W 参数。例如,通过 运行ning ping -c 1 -W 1 ...,ping 将只等待一秒钟,因此您的整个程序将花费大约 250 秒。
  2. 运行 并行 ping。您可以手动执行此操作,通常是使用 threads/processes 的 Pool(或者每个 ping 只使用一个 thread/process)。请注意,您的操作系统可能会强制限制每秒的 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)都应该可以正常工作。

使用scapy。无需在 Python 个线程中生成 ping 命令。