使用python eventlet并发ping

使用python的eventlet实现并发ping主机

import threading
import os
import re
import six
import socket
import subprocess
import sys
import time
import eventlet
from eventlet import GreenPool

eventlet.monkey_patch()

pool = GreenPool(100)


class Counter(object):

    def __init__(self):
        self.lock = threading.Lock()
        self.success_num = 0
        self.fail_num = 0

    def success(self):
        if self.lock.acquire():
            self.success_num += 1
            self.lock.release()

    def fail(self):
        if self.lock.acquire():
            self.fail_num += 1
            self.lock.release()

    def reset(self):
        self.success_num = self.fail_num = 0

    def __str__(self):
        s = "success: %s\nfail: %s" % (self.success_num, self.fail_num)
        return s


BATCH_COUNTER = Counter()


def execute_cmd(cmd):
    sub_pro = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    sub_pro.wait()
    output = "\n".join(sub_pro.communicate())
    return sub_pro.returncode, output


def convert_ip(ip=None, ip_str=None, ip_value=None):
    if ip is not None:
        if isinstance(ip, six.string_types):
            ip_str = ip
        elif isinstance(ip, six.integer_types):
            ip_value = ip
        else:
            return None

    if ip_str is not None:
        ip_s = ip_str.split(".")
        if len(ip_s) != 4:
            return 0
        try:
            _base = 1
            ip_value = 0
            for i in range(4):
                ip_value += int(ip_s[3 - i]) * _base
                _base *= 256
        except ValueError:
            return None
    elif ip_value is not None:
        _base = 256 ** 3
        ip_l = []
        _ip_value = ip_value
        for i in range(4):
            _value = _ip_value / _base
            _ip_value %= _base
            _base /= 256
            ip_l.append("%s" % _value)
        ip_str = ".".join(ip_l)
    else:
        return None

    return dict(ip_str=ip_str, ip_value=ip_value)


def calc_address_scope(address, prefix):
    prefix = int(prefix)
    ip_value = convert_ip(ip_str=address)['ip_value']
    host_mask = 2 ** (32 - prefix)
    start_ip = (ip_value / host_mask) * host_mask
    end_ip = start_ip + host_mask - 1
    return start_ip, end_ip


def executor(func, *args):
    try:
        if func(*args):
            BATCH_COUNTER.success()
            return True
    except Exception as e:
        pass
    BATCH_COUNTER.fail()
    return False


def exec_batch(func, l_args):
    start_time = time.time()
    for args in l_args:
        if isinstance(args, (list, tuple)) is False:
            args = [args]
        pool.spawn(executor, func, *args)
    print("exec batch completed. wait ...")
    pool.waitall()
    print(BATCH_COUNTER)
    end_time = time.time()
    use_time = end_time - start_time
    print("use time: %s" % use_time)
    BATCH_COUNTER.reset()


def demo_func(num):
    if num > 0:
        return True
    return False


def get_default_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("114.114.114.114", 53))
    return s.getsockname()[0]


def read_ip_file(ip_file):
    ips = []
    with open(ip_file, "r") as ri:
        content = ri.read()
        lines = content.split("\t")
        for line in lines:
            line = line.strip()
            if len(line) > 0:
                fa = re.findall(r"\d+\.\d+\.\d+\.\d+", line)
                ips.extend(fa)
        return ips


def ping_func(ip):
    cmd = ["ping", "-c", "5", "-W", "5", ip]
    code, output = execute_cmd(cmd)
    if code == 0:
        print("success %s" % ip)
        return True
    print("fail %s" % ip)
    return False


if __name__ == "__main__":
    """
    example 1:
    python batch_ping.py ip.text
    example 2:
    python batch_ping.py 10.10.10.1 10.10.10.2 10.10.10.3
    example 3:
    python batch_ping.py 10.180.210.250 22
    """
    argv = sys.argv
    l_ip = []
    if len(argv) == 1:
        local_ip = get_default_ip()
        ip_prefix = local_ip.rsplit(".", 1)[0]
        for i in range(1, 255):
            l_ip.append("%s.%s" % (ip_prefix, i))
    elif len(argv) == 2:
        ip_file = argv[1]
        l_ip = read_ip_file(ip_file)
    elif len(argv) == 3:
        start_ip, end_ip = calc_address_scope(argv[1], argv[2])
        for ip in range(start_ip, end_ip + 1):
            l_ip.append(convert_ip(ip)['ip_str'])
    else:
        l_ip.extend(argv[1:])
    exec_batch(ping_func, l_ip)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值