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

for loop in thread runs once in Python 3

我写了一个 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)

我只是在main函数中注释掉while循环,因此脚本创建一个线程并扫描10,000个IP。

以'google.com'为例,它在全球拥有众多IP地址:

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

示例输出:

Processing IP: 13.76.139.89
Ignore: 13.76.139.89

经过一些测试,我很确定 scanThread.run() 中的 for ... in 循环执行了一次。我是否在此代码段中做了不当的事情?

这可能是因为您正在主函数中清除列表。

    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) 这是复制列表,而不是使用传递的列表。