在网络子网中ping第一个可用主机
我写了一个小脚本,用Python编写,它可以对我学校无线网络的所有子网进行ping测试,并打印出连接到每个子网的计算机的IP地址和主机名。目前,我的设置是通过创建线程来处理每个ping请求。
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(和Angry IP扫描器)来完成这个任务,但我更想自己写一个脚本。
2 个回答
0
既然你在程序开始的时候就知道有多少个线程,你可以定期检查一下现在正在运行的线程数量,看看当前的线程数是否小于最开始的线程数。如果是这样,就可以结束当前的线程。
另外,最简单的方法其实是直接清空队列对象,不过我在文档里找不到这个方法。
1
最简单的方法就是让一个线程遍历整个子网,当它找到一个主机时就退出。
未经测试
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()