记个脚本,检测服务端口的

sourceforge打不开,在那个代理网上找到的n个地址ip,需要检测下,翻出之前学习的脚本,nnd,现在不用啥都忘了,这个记性真tmd的烂。
当时想作个检测服务端口的,并用curses显示作监控,不过问题最后,俺不会用curses分页,还有遇到同一个文件同时读写不可知问题,就搁置料。
大体上在同一目录需要一个monitor.list文件,里面是存放检测服务端口的,比如:
203.180.79.141:140,7171,7218
202.55.118.69:734,7094,7516
206.206.88.58:281,3547,11109
另外首先要创建一个.monitor.pickle文件,没作成自动生成的;
然后会将检测的信息写到这个pickle文件中,这个是为了方便实时监控使用的;
用法记下,俺懒,暂时能用则用算,
比如这个文件rescheck.py
python rescheck.py --daemon &
则按照terminal_monitor里面的time_interval设置的秒开始扫服务端口;
python rescheck.py --monitor
这个是在.monitor.pickle文件不为空的情况下,实时监控的简单画面;
python rescheck.py 可以运行一次,不作为daemon检测;
python rescheck.py -l 用来查看最终检测结果;
不过悲哀的是那些代理一个都不能用,好不容易有个意大利的能连上,还是打不开站点。
========================================================================
#!/usr/bin/python
# -*- encoding: utf-8 -*-
#检测结果写入pickle文件
import os,sys,re,time,datetime
import httplib,socket,cPickle as pickle,types
import threading,Queue,optparse,fcntl,signal,curses
RUNPATH = os.path.dirname(os.path.abspath(sys.argv[0]))
os.chdir(RUNPATH)
q = Queue.Queue()
tlist = []    #thread list,to control the max thread number
activechildpid = []
resdic = {}
freshsign = 0
signal.signal(signal.SIGCHLD,signal.SIG_IGN)
listfile = RUNPATH + '/monitor.list'
picklefile = RUNPATH + '/.monitor.pickle'
listpicklefile = RUNPATH + '/.liststatus.pickle'
def tcpres(host,port,timeout=2):
    '''
    tcp端口反应时间;
    '''
    global resdic
    #runend = 0
    tcpsock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    tcpsock.settimeout(timeout)
    stime = time.time()
    reserr = ''
    try:
        tcpsock.connect((host,int(port)),)
        restime = '%5.2f' %((time.time() - stime)*1000)
        restype = 1
    except socket.timeout:
        restype = 2
        restime = timeout * 1000
        reserr = 'TimeOut in %sS' %timeout
    except socket.error, errstr:
        restype = 3
        restime = 9999
        reserr = errstr[1]
    tcpsock.close()
    checktime = time.strftime('%Y-%m-%d %H:%M:%S')
    while restype == 0:  pass
    resdic[host][port] = [restype, restime, reserr,checktime ]
    dumpcp(resdic,picklefile)
def loadcp (file):
            tmpdic = {}
            fh = open(file,'rb')
            fcntl.flock(fh.fileno(),fcntl.LOCK_EX)
            fh.seek(0)
            #print "test file is", file
            try:
                tmpdic = pickle.load(fh)
            except:  pass
            fh.close()
            return tmpdic
def dumpcp_old(data,file):
    fh = open(file,'wb')
    if fh.tell() != 0:
        fh.close()
        dumpcp(data,file)
    else:  
        fcntl.flock(fh.fileno(),fcntl.LOCK_EX)
        fh.seek(0)
        pickle.dump(data,fh)
        fh.close()
def dumpcp(data,file):
    fh = open(file,'wb')
    pickle.dump(data,fh)
    fh.close()
   
def liststat(file1,file2):
    '''
    根据file1的modify time判断file1是否更改;
    file2存放file1最近的modify time;
    '''
    global freshsign
    stat = os.stat(file1).st_mtime
    freshsign = 0
    stat_old = ''
    if os.access(file2,os.R_OK):
        fh = open(file2,'rb')
        stat_old = pickle.load(fh)
        fh.close()
    if stat_old != stat:
        #print "old stat is:" , stat_old
        #print "new stat is:" , stat  
        freshsign = 1
        dumpcp(stat,file2)
def dicupdate(listfile,picklefile):
    '''
    根据listfile中host,port,和picklefile对比
    '''
    global resdic
   
    freshsign = 0
    newlist = []
    oldlist = []
   
    newdic = dicinit(listfile)
    olddic = loadcp(picklefile)
    if olddic:
        newlist = newdic.keys()
        oldlist = olddic.keys()
        newlist.sort(); oldlist.sort()
        if newlist != oldlist :  freshsign = 1
        else:
            for host in newdic.keys():
                newlist = newdic[host].keys()
                oldlist = olddic[host].keys()
                newlist.sort(); oldlist.sort()
                if newlist != oldlist :
                    freshsign = 1
                    break
        if freshsign:  resdic = dicinit(listfile)
    else:    resdic = dicinit(listfile)
def dicinit(file):
    #global resdic
    tmpdic = {}      
    for line in open(file,'ra'):
        vars = re.split(r':|,',line.strip())
        if len(vars) > 1:
            tmpdic[vars[0]] = {}
            for i in range(1,len(vars)):
                tmpdic[vars[0]][vars] = [0,9999,'hvnt update','']
    return tmpdic
   
# resdic = {host:{port:[restype, restime, restr, checktime],},}
# restype: 0 为未处理状态;1 为连接成功; 2为连接超时; 3为连接失败;
# restime: 单位为ms,默认以及失败为9999,超时默认为2000,其他为正常连接时间;
# restr: 连接状态说明,包括是否成功,失败,失败原因;
# checktime: 检测时间;   
   
def showpickle(picklefile,host='',port=''):
    tmpdic = {}
    tmpdic = loadcp(picklefile)
    #print "test resdic is:" , tmpdic
    if host:
        if port:  
            print host,port, tmpdic[host][port]
        else:  
            for port in tmpdic[host].keys():  print host,port, tmpdic[host][port]
    else:  
        for host in tmpdic.keys():
            for port in tmpdic[host].keys():  print host,port, tmpdic[host][port]
def monitorpickle(picklefile, outfile='/usr/local/apache/'):
    tmpdic = {}
    timeoutlist = []
    faillist = []
    successlist = []
    try:
        tmpdic = loadcp(picklefile)
    except:
        pass
    if tmpdic and type(tmpdic) is types.DictType:
        for host in tmpdic.keys():
            for port in tmpdic[host].keys():
               
                if tmpdic[host][port][0] == 2:  timeoutlist.append('%s:%s[%s]' %(host,port,tmpdic[host][port][3][11:]))
                if tmpdic[host][port][0] == 3: faillist.append('%s:%s[%s]' %(host,port,tmpdic[host][port][3][11:]))
                if tmpdic[host][port][0] == 1: successlist.append('%s:%s----%sms[%s]' %(host,port,tmpdic[host][port][1],tmpdic[host][port][3][11:]))
    timeoutlist.sort();faillist.sort();successlist.sort();
    return timeoutlist,faillist,successlist
def terminal_monitor(picklefile,time_interval=1):
    timeoutlist = []
    faillist = []
    successlist = []
   
    myscr = curses.initscr()
    curses.start_color()
    curses.noecho()
    curses.cbreak()
    myscr.keypad(1)
    myscr.nodelay(1)
    if curses.has_colors():
        curses.init_pair(1,1,0)
        curses.init_pair(2,3,0)
        curses.init_pair(3,2,0)
    pagecount = 0
    while 1:
            #myscr.addstr(10,75,str(pagecount))
   
            if myscr.getch() == ord('q'): break
            if myscr.getch() == ord('m'):  pagecount = pagecount + 1
            else:
                # show curses
                myscr.clear()
                myscr.addstr(4,5,time.strftime('%Y-%m-%d %H:%M:%S'))
                myscr.addstr(5,5,"连接失败",curses.color_pair(1) + curses.A_BOLD)
                myscr.addstr(5,40,"连接超时",curses.color_pair(2) + curses.A_BOLD)
                myscr.addstr(5,75,"连接正常",curses.color_pair(3))
                timeoutlist,faillist,successlist = monitorpickle(picklefile)
                #if pagecount > 0:  myscr.clear()  
                if pagecount > divmod(max(len(faillist),len(timeoutlist),len(successlist)),52)[0]: pagecount = 0         
                for i in range(0+52*pagecount,divmod(len(faillist),52)[1]+52*pagecount):
                    myscr.addstr(6+divmod(i,52)[1],5,faillist,curses.color_pair(1) + curses.A_BOLD )
                for i in range(0,len(timeoutlist)):
                    myscr.addstr(6+i,40,timeoutlist,curses.color_pair(2) + curses.A_BOLD )
                for i in range(0+52*pagecount,min(len(successlist),52*pagecount+52)):
                    myscr.addstr(6+divmod(i,52)[1],75,successlist,curses.color_pair(3))
                    #myscr.addstr(6,75,str(min(len(successlist),52*pagecount+52)))
               
                time.sleep(time_interval)
    myscr.refresh()
    myscr.clear()
    myscr.move(0,0)
    curses.nocbreak()
    myscr.keypad(0)
    curses.echo()
class tcpthread(threading.Thread):
    global tlist
    def __init__(self,host,port,timeout=2):
        threading.Thread.__init__(self)
        self.lk = threading.RLock()
        self.host = host
        self.port = port
        self.timeout = timeout
        self.restype = 0
        self.restime = ''
        self.reserr = ''
    def run(self):
        tcpres(self.host,self.port,self.timeout)
        tlist.remove(self)
def inpickle(listfile,listpicklefile,picklefile,timeout=2,maxthread=100):
    global tlist
    global resdic
   
    if not resdic:
        resdic = dicinit(listfile)
   
    for host in resdic.keys():
            for port in resdic[host].keys():
                #print "test resdic 2 is:" , resdic
                resthread = tcpthread(host,port,timeout)
                tlist.append(resthread)
                resthread.lk.acquire()
                while len(tlist) == maxthread:  pass
                resthread.start()
                resthread.lk.release()
    print "length of tlist is:",len(tlist)
    for t in tlist:
        t.join()        
   
def forktcpres():
    signal.signal(signal.SIGQUIT,signal.SIG_IGN)
    signal.signal(signal.SIGINT,signal.SIG_IGN)
    #print "childpid --%s  running time is" %os.getpid(), time.ctime()
    #runfin = 0
    stime = time.time()
    inpickle(listfile,listpicklefile,picklefile,timeout=2)
    #print (time.time() - stime)*1000
def reapchildpid():
    global activechildpid
    while  activechildpid:
        pid , stat = os.waitpid(0,os.WNOHANG)
        if not pid:  break
        activechildpid.remove(pid)   
            
def main():
    stime = time.time()
    global resdic
    global activechildpid
   
    parser = optparse.OptionParser(' %prog -h')
    parser.add_option('-l',dest='listsign', help='just list infos about response', action='store_true')
    parser.add_option('--daemon',dest='daemonsign', help='run as a server, every 1 mins', action='store_true')
    parser.add_option('--monitor',dest='monitorsign', help='monitor tcp state , every 1 mins', action='store_true')
    (options, args) = parser.parse_args()
    #print args
    listhost = ''
    listport = ''
    if args:
        for tmparg in args:
            if re.match(r'^\d+.\d+.\d+.\d+$',tmparg):  listhost = tmparg
            elif  re.match(r'^\d+$',tmparg):  listport = tmparg
    if options.listsign:
        showpickle(picklefile,listhost, listport)
    elif options.monitorsign:
        terminal_monitor(picklefile,1)
   
    elif options.daemonsign:
        dicupdate(listfile,picklefile)
        while 1:
                time.sleep(10)
                childpid = os.fork()
                if childpid == 0:
                    forktcpres()
                    os._exit(0)
                else:
                    #print "child pid-%s   run in " %i , time.ctime(),time.time()
                    #activechildpid.append(childpid)
                    pass
               
               #中断信号判断,SIGHUP, SIGKILL, SIGQUIT, SIGINT     
    else:  
        dicupdate(listfile,picklefile)
        inpickle(listfile,listpicklefile,picklefile,timeout=2)
        print (time.time() - stime)*1000
main()