os.system(" ping")调用非常慢

时间:2017-02-17 00:42:30

标签: python ping

我有以下脚本:

#!/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时,速度会快得多......而且它有效!

有没有办法可以让这个脚本更快?

2 个答案:

答案 0 :(得分:3)

默认情况下,ping等待10秒以使数据包到达。由于许多地址将不会被使用,或者具有这些地址的计算机将无法应答ICMP echo(ping)数据包,因此您需要等待2550秒,或者如果某些地址引发响应则稍微少一点。

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

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

  1. 在没有回应的时候提前放弃。传递-W参数。例如,通过运行ping -c 1 -W 1 ...,ping只会等待一秒钟,因此整个程序将需要大约250秒。
  2. 并行运行ping。您可以手动执行此操作,通常使用Pool个线程/进程(或每个ping只有一个线程/进程)。请注意,您的操作系统可能会强制限制每秒的ping数。例如,如果你将超时保持在10秒并设法同时运行所有ping,那么你的程序只需要10秒。
  3. 使用池的正确代码可能看起来像

    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)都可以正常工作。

答案 1 :(得分:0)

使用scapy。没有必要在Python线程中生成 ping 命令。