python中的快速ping扫描

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21225464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 22:20:57  来源:igfitidea点击:

Fast ping sweep in python

pythonbashpython-2.7ping

提问by digital_alchemy

So, I'm trying to get similar results using python as I do with a bash script.

所以,我试图像使用 bash 脚本一样使用 python 获得类似的结果。

Code for the bash script:

bash脚本的代码:

    #!/bin/bash

    for ip in $(seq 1 254); do
        ping -c 1 10.10.10.$ip | grep "bytes from" | cut -d " " -f 4 | cut -d ":" -f 1 &
    done

The thing that I would like to do is get the same results with similar speed. The issue that I've had with every version of the python script is that it takes a very long time to complete compared to the few seconds the batch script takes.

我想做的事情是以相似的速度获得相同的结果。我在每个版本的 python 脚本中遇到的问题是,与批处理脚本花费的几秒钟相比,它需要很长时间才能完成。

The batch file takes about 2 seconds to sweep a /24 network while the the best I can get with the python script is about 5-8 minutes.

批处理文件大约需要 2 秒来扫描 /24 网络,而我使用 python 脚本可以获得的最佳时间约为 5-8 分钟。

Latest version of python script:

最新版本的python脚本:

import subprocess

cmdping = "ping -c1 10.10.10."

for x in range (2,255):
    p = subprocess.Popen(cmdping+str(x), shell=True, stderr=subprocess.PIPE)

    while True:
        out = p.stderr.read(1)
        if out == '' and p.poll() != None:
            break
        if out != '':
            sys.stdout.write(out)
            sys.stdout.flush()

I've tried several different ways in python but can't get anywhere near the speed of the bash script.

我在 python 中尝试了几种不同的方法,但无法接近 bash 脚本的速度。

Any suggestions?

有什么建议?

采纳答案by mojo

Multiprocessing

多处理

#!/usr/bin/python2

import multiprocessing
import subprocess
import os

def pinger( job_q, results_q ):
    DEVNULL = open(os.devnull,'w')
    while True:
        ip = job_q.get()
        if ip is None: break

        try:
            subprocess.check_call(['ping','-c1',ip],
                                  stdout=DEVNULL)
            results_q.put(ip)
        except:
            pass

if __name__ == '__main__':
    pool_size = 255

    jobs = multiprocessing.Queue()
    results = multiprocessing.Queue()

    pool = [ multiprocessing.Process(target=pinger, args=(jobs,results))
             for i in range(pool_size) ]

    for p in pool:
        p.start()

    for i in range(1,255):
        jobs.put('192.168.1.{0}'.format(i))

    for p in pool:
        jobs.put(None)

    for p in pool:
        p.join()

    while not results.empty():
        ip = results.get()
        print(ip)