import socket
import threading
import time
from concurrent.futures import ThreadPoolExecutor, as_completed

class PortScanner:
    def __init__(self, target_host, start_port, end_port, timeout=3, max_threads=1000):
        self.target_host = target_host
        self.start_port = start_port
        self.end_port = end_port
        self.timeout = timeout
        self.max_threads = max_threads
        self.open_ports = []
        self.lock = threading.Lock()
        
    def scan_port(self, port):
        """扫描单个端口"""
        try:
            # 创建socket对象
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
                sock.settimeout(self.timeout)
                # 尝试连接端口
                result = sock.connect_ex((self.target_host, port))
                
                if result == 0:
                    with self.lock:
                        self.open_ports.append(port)
                    return port, True
                else:
                    return port, False
        except Exception as e:
            return port, False
    
    def run_scan(self):
        """执行端口扫描"""
        print(f"开始扫描 {self.target_host} 的端口 {self.start_port}-{self.end_port}")
        start_time = time.time()
        
        # 使用线程池执行扫描任务
        with ThreadPoolExecutor(max_workers=self.max_threads) as executor:
            # 创建所有端口的扫描任务
            future_to_port = {
                executor.submit(self.scan_port, port): port 
                for port in range(self.start_port, self.end_port + 1)
            }
            
            # 处理完成的任务
            for future in as_completed(future_to_port):
                port = future_to_port[future]
                try:
                    port, is_open = future.result()
                    if is_open:
                        print(f"端口 {port} 是开放的")
                except Exception as e:
                    print(f"扫描端口 {port} 时发生错误: {e}")
        
        end_time = time.time()
        print(f"\n扫描完成! 耗时: {end_time - start_time:.2f} 秒")
        print(f"发现的开放端口: {sorted(self.open_ports)}")

if __name__ == "__main__":
    # 配置参数
    TARGET_HOST = "192.168.8.11"
    START_PORT = 10000
    END_PORT = 60000
    TIMEOUT = 3
    MAX_THREADS = 1000
    
    # 创建并运行扫描器
    scanner = PortScanner(TARGET_HOST, START_PORT, END_PORT, TIMEOUT, MAX_THREADS)
    scanner.run_scan()