2016-08-04 59 views
1

因此,昨天我正在練習我在過去幾天學到的知識,並決定創建一個腳本來掃描本地網絡中的所有IP,並檢查哪些IP正在使用。Python pinging本地IP

我用子使用與給定超時「ping」命令,以及其他一些庫,如docopt,線程和時間共同任務,如處理命令行參數,線程,等待代碼等..

這裏的腳本:

""" ipcheck.py - Getting available IPs in a network. 


Usage: 
    ipcheck.py -h | --help 
    ipcheck.py PREFIX 
    ipcheck.py [(-n <pack_num> PREFIX) | (-t <timeout> PREFIX)] 

Options: 
    -h --help  Show the program's usage. 
    -n --packnum  Number of packets to be sent. 
    -t --timeout  Timeout in miliseconds for the request. 
""" 

import sys, os, time, threading 
from threading import Thread 
from threading import Event 
import subprocess 
import docopt 


ips = [] # Global ping variable 


def ping(ip, e, n=1, time_out=1000): 

    global ips 

    # FIX SO PLATFORM INDEPENDENT 
    # Use subprocess to ping an IP 
    try: 
     dump_file = open('dump.txt', 'w') 
     subprocess.check_call("ping -q -w%d -c%s %s" % (int(time_out), int(n), ip), 
     shell=True, stdout=dump_file, stderr=dump_file) 
    except subprocess.CalledProcessError as err: 
     # Ip did not receive packets 
     print("The IP [%s] is NOT AVAILABLE" % ip) 
     return 
    else: 
     # Ip received packets, so available 
     print("The IP [%s] is AVAILABLE" % ip) 
     #ips.append(ip) 
    finally: 
     # File has to be closed anyway 
     dump_file.close() 

     # Also set the event as ping finishes 
     e.set() 
     ips.append(1) 


def usage(): 
    print("Helped init") 

def main(e): 

    # variables needed 
    timeout = 1000 
    N_THREADS = 10 


    # Get arguments for parsing 
    arguments = docopt.docopt(__doc__) 

    # Parse the arguments 
    if arguments['--help'] or len(sys.argv[1:]) < 1: 
     usage() 
     sys.exit(0) 
    elif arguments['--packnum']: 
     n_packets = arguments['--packnum'] 
    elif arguments['--timeout']: 
     timeout = arguments['--timeout'] 
    prefix = arguments['PREFIX'] 


    # Just an inner function to reuse in the main 
    # loop. 
    def create_thread(threads, ip, e): 

     # Just code to crete a ping thread 
     threads.append(Thread(target=ping, args=(ip, e))) 
     threads[-1].setDaemon(True) 
     threads[-1].start() 
     return 


    # Do the threading stuff 
    threads = [] 

    # Loop to check all the IP's 
    for i in range(1, 256): 
     if len(threads) < N_THREADS: 

      # Creating and starting thread 
      create_thread(threads, prefix+str(i), e) 

     else: 
      # Wait until a thread finishes 
      e.wait() 

      # Get rid of finished threads 
      to_del = [] 
      for th in threads: 
       if not th.is_alive(): to_del.append(th) 
      for th in to_del: threads.remove(th) 

      # Cheeky clear init + create thread 
      create_thread(threads, prefix+str(i), e) 
      e.clear() 

    time.sleep(2*timeout/1000) # Last chance to wait for unfinished pings 
    print("Program ended. Number of threads active: %d." % threading.active_count()) 

if __name__ == "__main__": 
    ev = Event() 
    main(ev) 

我遇到的問題是,雖然我設置超時(以毫秒爲單位)ping命令,某些線程不完成某種原因。我通過使所有線程守護進程並在程序結束後等待兩次超時(主要爲最後幾行)來暫時解決這個問題,但這不能按預期工作,有些線程在睡眠後仍未完成。

這是關於命令ping本身或在我的設計中有問題嗎?

和平!

+0

您是否試圖讓它在shell(cmd)命令中執行它? – Rootel

+0

是的,我在shell上運行命令,它永遠不會超時。這就是爲什麼-w命令在那裏的原因,所以它不會等待比這更長的響應時間。 –

+0

但在代碼中,它似乎仍然有時會繼續,並且不會終止。 –

回答