欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python获取网段内ping通IP的方法

程序员文章站 2022-11-30 14:19:27
问题描述 在某些问题背景下,需要确认是否多台终端在线,也就是会使用我们牛逼的ping这个命令,做一些的ping操作,如果需要确认的设备比较少,也还能承受。倘若,在手中维护...

问题描述

在某些问题背景下,需要确认是否多台终端在线,也就是会使用我们牛逼的ping这个命令,做一些的ping操作,如果需要确认的设备比较少,也还能承受。倘若,在手中维护的设备很多。那么这无疑会变成一个恼人的问题。脚本的作用就凸显了。另外,我们需要使用多线程的一种措施,否则单线程很难在很短的时间内拿到统计结果。

应用背景

有多台设备需要维护,周期短,重复度高;

单台设备配备多个ip,需要经常确认网络是否通常;

等等其他需要确认网络是否畅通的地方

问题解决

使用python自带threading模块,实现多线程的并发操作。如果本机没有相关的python模块,请使用pip install package name安装之。

threading并发ping操作代码实现

这部分代码取材于网络,忘记是不是*,这不重要,重要的是这段代码或者就有价值,代码中部分关键位置做了注释,可以自行定义ip所属的网段,以及使用的线程数量。从鄙人的观点来看是一段相当不错的代码,

# -*- coding: utf-8 -*-

import sys
import os
import platform
import subprocess
import queue
import threading
import ipaddress
import re

def worker_func(pingargs, pending, done):
 try:
  while true:
   # get the next address to ping.
   address = pending.get_nowait()

   ping = subprocess.popen(pingargs + [address],
    stdout = subprocess.pipe,
    stderr = subprocess.pipe
   )
   out, error = ping.communicate()

   if re.match(r".*, 0% packet loss.*", out.replace("\n", "")):
    done.put(address)

   # output the result to the 'done' queue.
 except queue.empty:
  # no more addresses.
  pass
 finally:
  # tell the main thread that a worker is about to terminate.
  done.put(none)

# the number of workers.
num_workers = 14

plat = platform.system()
scriptdir = sys.path[0]
hosts = os.path.join(scriptdir, 'hosts.txt')

# the arguments for the 'ping', excluding the address.
if plat == "windows":
 pingargs = ["ping", "-n", "1", "-l", "1", "-w", "100"]
elif plat == "linux":
 pingargs = ["ping", "-c", "1", "-l", "1", "-s", "1", "-w", "1"]
else:
 raise valueerror("unknown platform")

# the queue of addresses to ping.
pending = queue.queue()

# the queue of results.
done = queue.queue()

# create all the workers.
workers = []
for _ in range(num_workers):
 workers.append(threading.thread(target=worker_func, args=(pingargs, pending, done)))

# put all the addresses into the 'pending' queue.
for ip in list(ipaddress.ip_network(u"10.69.69.0/24").hosts()):
 pending.put(str(ip))

# start all the workers.
for w in workers:
 w.daemon = true
 w.start()

# print out the results as they arrive.

numterminated = 0
while numterminated < num_workers:
 result = done.get()
 if result is none:
  # a worker is about to terminate.
  numterminated += 1
 else:
  print result # print out the ok ip

# wait for all the workers to terminate.
for w in workers:
 w.join()

使用资源池的概念,直接使用gevent这么python模块提供的相关功能。

资源池代码实现

这部分代码,是公司的一个python方面的大师的作品,鄙人为了这个主题做了小调整。还是那句话,只要代码有价值,有生命力就是对的,就是值得的。

# -*- coding: utf-8 -*-

from gevent import subprocess
import itertools
from gevent.pool import pool

pool = pool(100) # concurrent action count

ips = itertools.product((10, ), (69, ), (69, ), range(1, 255))

def get_response_time(ip):
 try:
  out = subprocess.check_output('ping -c 1 -w 1 {}.{}.{}.{}'.format(*ip).split())
  for line in out.splitlines():
   if '0% packet loss' in line:
    return ip
 except subprocess.calledprocesserror:
  pass

 return none

resps = pool.map(get_response_time, ips)
reachable_resps = filter(lambda (ip): ip != none, resps)

for ip in reachable_resps:
 print ip

github目录:git@github.com:qcq/code.git 下的子目录utils内部。

以上这篇python获取网段内ping通ip的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。