使用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)