Python子网Ping扫描存活主机及端口扫描程序问题求助
解决子网Ping扫描+端口扫描的Python脚本问题
嘿,我看你现在卡在子网存活主机探测加端口扫描的脚本上了,先别急,咱们先从你给出的简化版脚本入手,一步步捋清楚问题和解决办法~
首先先把你提供的不完整代码贴出来,方便咱们分析:
#!/usr/bin/env python import socket import ipaddress def portscan(host): sock = socket.socket(socket.AF_INET, socket.SOCK_STR...
你当前脚本的核心问题
- Ping扫描逻辑缺失:你提到要先探测存活主机存入数组,但当前完全没有这部分代码,直接遍历子网会浪费大量时间在不存活的主机上
- 端口扫描函数不完整:
socket.SOCK_STR是笔误,应该是SOCK_STREAM(TCP套接字),而且没有指定端口范围、超时处理和异常捕获,很容易导致程序崩溃 - 无并发处理:单线程扫描整个子网+端口会慢到离谱,实际使用必须加并发
- 存活主机的存储与传递逻辑空白:你说要把存活主机存数组,但当前没有任何相关代码
修正后的完整可运行脚本
我给你写了一个补全逻辑、优化性能的版本,注释都写得很清楚:
#!/usr/bin/env python import socket import ipaddress import subprocess import threading from typing import List # 端口扫描函数,支持指定要扫描的端口列表 def portscan(host: str, ports: List[int]): print(f"开始扫描主机 {host} 的端口...") for port in ports: try: # 创建TCP套接字(SOCK_STREAM是正确的参数,你之前写的SOCK_STR是笔误) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置0.5秒超时,避免等待太久拖慢速度 sock.settimeout(0.5) # connect_ex返回0表示端口开放,非0表示关闭或不可达 result = sock.connect_ex((host, port)) if result == 0: print(f"✅ 主机 {host} 的端口 {port} 开放") sock.close() except Exception as e: # 捕获异常,避免单个端口扫描失败导致整个程序崩溃 print(f"❌ 扫描主机 {host} 端口 {port} 时出错: {str(e)}") # Ping探测存活主机,跨平台兼容Windows/Linux/macOS def ping_host(host: str) -> bool: # 根据系统选择ping的参数:Windows用-n,类Unix用-c param = '-n' if subprocess.os.name == 'nt' else '-c' # 发送1个包,超时1秒,避免长时间等待 command = ['ping', param, '1', '-W', '1', host] try: # 执行ping命令,不输出到控制台 result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False) # 返回码为0表示ping成功,主机存活 return result.returncode == 0 except Exception as e: print(f"Ping主机 {host} 时出错: {str(e)}") return False def main(): # 你可以修改这里的子网和要扫描的端口 target_subnet = "192.168.0.0/24" target_ports = [21, 22, 80, 443, 3389, 8080] alive_hosts: List[str] = [] print(f"🔍 开始扫描子网 {target_subnet} 的存活主机...") # 遍历子网中的每一个IP地址 for ip in ipaddress.IPv4Network(target_subnet, strict=False): ip_str = str(ip) if ping_host(ip_str): print(f"🟢 主机 {ip_str} 存活") alive_hosts.append(ip_str) else: print(f"🔴 主机 {ip_str} 不存活") print("\n🚀 开始对存活主机进行端口扫描...") # 用多线程加速扫描,每个存活主机开一个线程 threads = [] for host in alive_hosts: thread = threading.Thread(target=portscan, args=(host, target_ports)) threads.append(thread) thread.start() # 等待所有线程完成扫描 for thread in threads: thread.join() print("\n🎉 扫描全部完成!") if __name__ == "__main__": main()
关键优化点说明
- 存活主机探测:用系统自带的
ping命令,跨平台且不需要特殊权限(如果用纯Python的ICMP探测,Linux/macOS需要root权限) - 端口扫描完善:修正了套接字参数错误,添加超时处理,捕获异常避免崩溃
- 多线程并发:每个存活主机开独立线程扫描端口,大幅提升扫描速度
- 清晰的结果输出:用 emoji 区分状态,方便快速查看
额外优化建议
- 可以用
concurrent.futures.ThreadPoolExecutor替代手动管理线程,代码会更简洁 - 如果需要更精准的ICMP探测,可以使用
scapy库(需要额外安装) - 可以把扫描结果写入文件,比如CSV格式,方便后续分析
- 可以增加命令行参数,让用户在运行时指定子网、端口范围等,不用修改代码
内容的提问来源于stack exchange,提问作者Brandon McGrath
相关产品推荐
相关产品推荐

