代码之家  ›  专栏  ›  技术社区  ›  J.K

线程中的for循环在Python 3中运行一次

  •  0
  • J.K  · 技术社区  · 9 年前

    我已经编写了一个Python脚本来获取IP地址列表的证书,以匹配域:

    #! /usr/bin/env python3
    
    import ssl
    import socket
    import argparse
    from threading import Thread, Lock
    from itertools import islice
    
    class scanThread(Thread):
        def __init__(self,iplist, q, hostname, port):
            Thread.__init__(self)
            self.iplist = iplist
            self.hostname = hostname
            self.port = port
            self.queue = q
    
        def dummy(self,ip):
            print("Running dummy")
    
        def checkCert(self, ip):
            print('Processing IP: %s' % ip )
            ctx = ssl.create_default_context()
            s = ctx.wrap_socket(socket.socket(), server_hostname=self.hostname)
            try:
                s.connect((ip, self.port))
                cert = s.getpeercert()
                if cert['subjectAltName'][0][1].find(hostname) != -1:
                    return ip
            except (ssl.CertificateError, ssl.SSLError):
                print('Ignore: %s' % ip)
            finally:
                s.close()
                return
    
        def run(self):
            for ip in self.iplist:
                returnIP = self.checkCert(ip)
                if returnIP:
                    self.queue.append(ip)
    
    def main(l, hostname, port):
        iplist = []
        threads = []
        hostPool = []
        with open(l,'r') as f:
            #while True:
            iplist.extend([f.readline().strip() for x in islice(f, 10000)])
            #print(iplist)
            t = scanThread(iplist, hostPool, hostname, port)
            t.start()
            threads.append(t)
            iplist.clear()
    
        for t in threads:
            t.join()
    
        for h in hostPool:
            print(h)
    
    
    
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser()
        parser.add_argument("hostname",help="root hostname")
        parser.add_argument("-l","--list",required=True, help="IP list for scanning")
        parser.add_argument("-p","--port", nargs='?', const=443, default=443, type=int, help="port to scan")
        arg = parser.parse_args()
        main(arg.list,arg.hostname, arg.port)
    

    我只是说说而已 while 循环输入 main 函数,因此脚本创建一个线程并扫描10000个IP。

    以“谷歌”为例。例如,它在全球拥有众多IP地址:

    ./google.py -l 443.txt google.com
    

    输出示例:

    Processing IP: 13.76.139.89
    Ignore: 13.76.139.89
    

    经过一些测试,我很确定 for ... in 循环输入 scanThread.run() 执行了一次。我在这段代码中做了什么不合适的事情吗?

    1 回复  |  直到 9 年前
        1
  •  0
  •   Arun Ghosh    9 年前

        t = scanThread(iplist, hostPool, hostname, port)
        t.start()
        threads.append(t)
        iplist.clear() // here you are clearing.
    

    class scanThread(Thread):
        def __init__(self,iplist, q, hostname, port):
            Thread.__init__(self)
            self.iplist = list(iplist)
    

    self.iplist = list(iplist) 这是复制列表,而不是使用传递的列表。