2009-12-10 37 views
2

我已经用Python编写了一个小脚本,可以ping通我学校无线网络的所有子网,并打印出连接到网络中每个子网的计算机的IP地址和主机名。我目前的设置是我依靠创建线程来处理每个ping请求。Pinging网络子网中的第一个可用主机

from threading import Thread 
import subprocess 
from Queue import Queue 
import time 
import socket 

#wraps system ping command 
def ping(i, q): 
    """Pings address""" 
    while True: 
     ip = q.get() 
     #print "Thread %s: Pinging %s" % (i, ip) 
     result = subprocess.call("ping -n 1 %s" % ip, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
     #Avoid flooding the network with ping requests 
     time.sleep(3) 
     if result == 0: 

      try: 
       hostname=socket.gethostbyaddr(ip) 
       print "%s (%s): alive" % (ip,hostname[0]) 
      except: 
       print "%s: alive"%ip 
     q.task_done() 

num_threads = 100 
queue = Queue() 
addresses=[] 
#Append all possible IP addresses from all subnets on wireless network 
for i in range(1,255): 
    for j in range(1,254): 
     addresses.append('128.119.%s.%s'%(str(i),str(j))) 
#Spawn thread pool 
for i in range(num_threads): 
    worker = Thread(target=ping, args=(i, queue)) 
    worker.setDaemon(True) 
    worker.start() 
#Place work in queue 
for ip in addresses: 
    queue.put(ip) 
#Wait until worker threads are done to exit  
queue.join() 

但是,我想修改我的脚本,以便它只查找子网中的第一个可用主机。这意味着,假设我有以下子网(128.119.177.0/24),第一个可用主机是128.119.177.20。我希望我的脚本在成功联系128.119.177.20后停止对128.119.177.0/24中的其余主机执行ping操作。我想对我网络上的每个子网(128.119.0.1 - 128.119.255.254)重复这一点。鉴于我目前的设置,做出这一改变的最佳做法是什么?我正在考虑做一些类似队列的列表(其中每个队列为其中一个子网保留255个IP地址)并且每个队列都有一个线程处理(除非在Windows上可以在Python中产生多少线程) 。

编辑:我玩过nmap(和愤怒的IP扫描仪)这项任务,但我有兴趣追求写我自己的脚本。

+2

你有没有考虑过使用nmap?另外,要小心,因为虽然你在做什么可能是无辜的,它可能看起来像在工作中的饼干。 – gahooa 2009-12-10 18:49:30

+2

+1 gahooa。 @rohanbk,同时检查你学校的网络使用政策。我在一所大学工作了多年,这违反了使用政策,并被禁止(甚至可能被驱逐)。 – 2009-12-10 19:04:09

回答

1

最简单的情况是让线程在整个子网中工作,并在找到主机时退出。

UNTESTED

from Queue import Queue 
import time 
import socket 

#wraps system ping command 
def ping(i, q): 
    """Pings address""" 
    while True: 
     subnet = q.get() 
     # each IP addresse in subnet 
     for ip in (subnet=str(x) for x in range(1,254)): 
      #print "Thread %s: Pinging %s" % (i, ip) 
      result = subprocess.call("ping -n 1 %s" % ip, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
      #Avoid flooding the network with ping requests 
      time.sleep(3) 
      if result == 0: 

       try: 
        hostname=socket.gethostbyaddr(ip) 
        print "%s (%s): alive" % (ip,hostname[0] 
       except: 
        print "%s: alive"%ip 
       break 
     q.task_done() 

num_threads = 100 
queue = Queue() 

#Put all possible subnets on wireless network into a queue 
for i in range(1,255): 
    queue.put('128.119.%s.'%i) 

#Spawn thread pool 
for i in range(num_threads): 
    worker = Thread(target=ping, args=(i, queue)) 
    worker.setDaemon(True) 
    worker.start() 

#Wait until worker threads are done to exit  
queue.join() 
0

既然你知道有多少你在运行之初得到了线程,你可以定期检查线程的当前数量运行,看是否nowThreadCount < startThreadCount。如果它是真的终止当前线程。

PS:最简单的方法是只清除队列对象,但我无法在文档中找到它。