Python3线程,试图同时ping多个IP /测试端口

时间:2016-04-12 19:18:08

标签: python multithreading sockets

下面的完整(非工作)代码

此处的完整(有效,无线程)代码:http://pastebin.com/KUYzNtT2

我写了一个小脚本,执行以下操作:

  1. 从数据库中提取网络信息
  2. 在cidr中ping每个IP(即 - 192.168.0.0/24);如果它已经启动,请测试某个端口是否打开
  3. 显示结果
  4. 这很好用,但我想实现线程以使脚本运行得更快;因为我有成千上万的IP要扫描,这需要永远。

    我玩过线程教程,但似乎无法掌握如何在我的脚本中实现它。

    任何想法或建议都表示赞赏。

    编辑:我根据本指南采用了不同的方向:http://chriskiehl.com/article/parallelism-in-one-line/

    现在我运行该程序并获取:File "port_test.py", line 39, in display_results for (client, location, cidr) in results: ValueError: too many values to unpack (expected 3) 而且我不明白为什么。想法?

    **编辑:我想我弄清楚它失败的原因,看起来像pool.map只需要一个数据点。如果我只查询数据库中的CIDR而不是其他两列,则程序开始吐出数据(比之前更快)。所以现在我需要弄清楚如何将其他两列添加到结果中,然后将结果排序为有意义(结果没有顺序,我认为这是有意义的)

    #! /usr/bin/python
    # Import modules
    import socket
    import subprocess
    import ipaddress
    import mysql.connector
    import configparser
    import logging
    import coloredlogs
    from multiprocessing.dummy import Pool as ThreadPool
    
    #logging.basicConfig(format='%(levelname)s:%(message)s',level=logging.INFO)
    
    
    coloredlogs.install(level='DEBUG')
    coloredlogs.DEFAULT_LOG_FORMAT = '%(asctime)s -- %(message)s'
    # read from the config file
    config = configparser.ConfigParser()
    config.read('config.ini')
    db=config['mysql']
    net=config['network']
    port = int(net['port'])
    
    # create the connection, connect, and setup the query
    cnx = mysql.connector.connect(user=db['user'], database=db['database'], password=db['password'])
    cursor = cnx.cursor()
    
    query = ("select fw.net_cidr as cidr "
            "from firewalls fw "
                "left join clients c on c.id = fw.client_id "
                "left join locations l on l.id = fw.location_id "
                    "where fw.net_cidr <> '' and c.active = '1' and fw.active = '1'")
    
    cursor.execute(query)
    results = cursor.fetchall()
    
    def display_results(results):
    # execute and display the results
        for (cidr) in results:
                logging.info("{} --> ".format(cidr))
                try:
                    # Prompt the user to input a network address
                    net_addr = str(cidr)
    
                    # Create the network
                    ip_net = ipaddress.ip_network(net_addr)
    
                     # Get all hosts on that network
                    all_hosts = list(ip_net.hosts())
                except ValueError as e:
                    logging.warning(e)
                    continue
    
                # For each IP address in the subnet, test to see if port 3389 is open
                for i in range(len(all_hosts)):
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.settimeout(.25)
                    result = sock.connect_ex((str(all_hosts[i]),port))
                    if result == 0:
                            logging.info(str(all_hosts[i]) + ": " + net['port'] + " is open")
                else:
                        logging.debug(str(all_hosts[i]) + ": " + net['port'] + " is not open")
    
    # make a pool of workers
    pool = ThreadPool(4)
    
    # ping the cidrs in their own thread
    pool.map(display_results, results)
    pool.close()
    pool.join()
    
    # close the database connection
    cursor.close()
    cnx.close()
    

1 个答案:

答案 0 :(得分:-1)

最初抓取所有数据并将其存储在Queue中。

创建一个连续运行的函数,直到Queue为空(即while my_queue.empty() is False

使用Queue的{​​{1}}方法抓取Queue中的第一个对象。

然后处理它。

根据需要初始化多个线程,它们将一直执行,直到get()为空。