由于项目中需要检测内网中的所有在线主机,并把不在线的主机通过报警发送到管理中心,就用python实现了一个多线程的类似扫描器的小工具,主要通过ping来实现对目标主机的检测。由于一些防火墙会对ping进行过滤,所以对外部网段的结果不一定很准确。以下为做了部分修改后的代码:
# -*- encode:utf-8 -*-
import os, Queue, re, time, sys
import threading
queue2 = Queue.Queue( ) class CThread(threading.Thread):
def __init__( self, ipList ):
threading.Thread.__init__( self )
self.__ipList = ipList #需要ping的目标主机列表
self.__nPackage = 1 #ping目标主机发包数
def run( self ):
if sys.platform and sys.platform[:3]=='win':
cmd = 'ping -n %d ' % (self.__nPackage)
else:
cmd = 'ping -c %d ' % (self.__nPackage)
for ip in self.__ipList:
print 'pinging %s' % ip
sRst = os.popen( cmd+ip ).read( )
if re.search( 'timeds*out', sRst ) and
(not re.match( 'ttl', sRst ) or
not re.match( 'TTL', sRst )):
queue.put( ip )
else:
queue2.put( ip ) class CPing:
def __init__( self, ipList ):
self.__ipList = ipList #需要ping的目标主机列表
self.__nThread = 50 #开启的ping线程数
def Ping( self ):
nBegin = time.time( )
listThread = []
n = len(self.__ipList)/self.__nThread+1
nSum = 0
for i in range(self.__nThread):
if i*n+n < len(self.__ipList):
nSum += 1
trd = CThread( self.__ipList[i*n:i*n+n] )
print 'thread%d' % i, self.__ipList[i*n:i*n+n]
else:
if not self.__ipList[i*n:]:
break
nSum += 1
trd = CThread( self.__ipList[i*n:] )
print 'thread%d' % i, self.__ipList[i*n:]
listThread.append( trd )
trd.start( )
for i in range(nSum):
listThread[i].join( )
nEnd = time.time( )
print '共用%d秒'.decode('utf-8') % (nEnd-nBegin) def main( ):
ipList = []
for i in xrange( 11, 21 ):
ipList.append( '192.168.0.'+str(i) )
ping.Ping( )
print 'not connected:'
while not queue.empty( ):
print queue.get( )
print 'connected:'
while not queue2.empty( ):
print queue2.get( ) if __name__ == '__main__':
main( )
import os, Queue, re, time, sys
import threading
queue
= Queue.Queue( )queue2 = Queue.Queue( ) class CThread(threading.Thread):
def __init__( self, ipList ):
threading.Thread.__init__( self )
self.__ipList = ipList #需要ping的目标主机列表
self.__nPackage = 1 #ping目标主机发包数
def run( self ):
if sys.platform and sys.platform[:3]=='win':
cmd = 'ping -n %d ' % (self.__nPackage)
else:
cmd = 'ping -c %d ' % (self.__nPackage)
for ip in self.__ipList:
print 'pinging %s' % ip
sRst = os.popen( cmd+ip ).read( )
if re.search( 'timeds*out', sRst ) and
(not re.match( 'ttl', sRst ) or
not re.match( 'TTL', sRst )):
queue.put( ip )
else:
queue2.put( ip ) class CPing:
def __init__( self, ipList ):
self.__ipList = ipList #需要ping的目标主机列表
self.__nThread = 50 #开启的ping线程数
def Ping( self ):
nBegin = time.time( )
listThread = []
n = len(self.__ipList)/self.__nThread+1
nSum = 0
for i in range(self.__nThread):
if i*n+n < len(self.__ipList):
nSum += 1
trd = CThread( self.__ipList[i*n:i*n+n] )
print 'thread%d' % i, self.__ipList[i*n:i*n+n]
else:
if not self.__ipList[i*n:]:
break
nSum += 1
trd = CThread( self.__ipList[i*n:] )
print 'thread%d' % i, self.__ipList[i*n:]
listThread.append( trd )
trd.start( )
for i in range(nSum):
listThread[i].join( )
nEnd = time.time( )
print '共用%d秒'.decode('utf-8') % (nEnd-nBegin) def main( ):
ipList = []
for i in xrange( 11, 21 ):
ipList.append( '192.168.0.'+str(i) )
ping
= CPing( ipList )ping.Ping( )
print 'not connected:'
while not queue.empty( ):
print queue.get( )
print 'connected:'
while not queue2.empty( ):
print queue2.get( ) if __name__ == '__main__':
main( )
上面的代码中主要通过两种手段来加快扫描速度,一个是通过多线程扫描,另一个方法是对每台目标主机只发送一个数据包,这样对每台主机的通信时间只需要一个RTT。