上一篇
Python检测端口是否开放教程 - 简单高效的端口扫描方法
- Python
- 2025-07-29
- 869
Python检测端口是否开放教程
作者: 网络技术专家 |
发布日期: 2023年10月15日 |
阅读时间: 8分钟
内容大纲:
- 端口检测的基本原理
- Python socket模块介绍
- 单端口检测实现
- 多端口扫描实现
- 完整端口扫描器代码
- 应用场景与注意事项
为什么需要检测端口开放状态?
端口检测是网络管理和网络安全的基础操作之一,主要用途包括:
- 检查服务器特定服务是否正常运行(如HTTP/80,HTTPS/443)
- 网络安全评估和漏洞扫描
- 网络故障排查
- 监控网络服务可用性
端口检测基本原理
端口检测的基本原理是尝试与目标主机的特定端口建立TCP连接:
- 创建TCP socket对象
- 设置适当的超时时间
- 尝试连接目标主机的指定端口
- 根据连接结果判断端口状态:
- 连接成功 → 端口开放
- 连接被拒绝 → 端口关闭
- 连接超时 → 端口可能被防火墙过滤
Python socket模块介绍
Python内置的socket
模块提供了访问操作系统Socket接口的功能,是网络编程的核心模块。
主要方法:
socket()
- 创建新的socket对象connect()
- 连接到远程地址send()
- 发送数据recv()
- 接收数据close()
- 关闭连接
单端口检测实现
以下是一个简单的Python函数,用于检测单个端口状态:
import socket def check_port(host, port, timeout=2): """ 检测指定主机和端口是否开放 :param host: 目标主机IP或域名 :param port: 目标端口 :param timeout: 超时时间(秒) :return: 布尔值,True表示端口开放 """ try: # 创建TCP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout) # 尝试连接 result = sock.connect_ex((host, port)) # 判断连接结果 if result == 0: print(f"端口 {port} 是开放的") return True else: print(f"端口 {port} 是关闭的") return False except socket.error as err: print(f"检测端口 {port} 时出错: {err}") return False finally: # 确保关闭socket连接 sock.close() # 使用示例 check_port("www.example.com", 80) # 检测HTTP端口 check_port("192.168.1.1", 22) # 检测SSH端口
代码说明:
socket.AF_INET
表示使用IPv4地址socket.SOCK_STREAM
表示使用TCP协议connect_ex()
返回错误代码而不是抛出异常- 使用try-except-finally确保资源正确释放
多端口扫描实现
实际应用中,我们通常需要扫描多个端口。下面是增强版本:
import socket import concurrent.futures def scan_ports(host, ports, max_workers=100, timeout=1): """ 扫描目标主机的多个端口 :param host: 目标主机 :param ports: 端口列表 :param max_workers: 最大并发线程数 :param timeout: 每个连接的超时时间 """ open_ports = [] print(f"开始扫描主机: {host}") print("-" * 50) # 使用线程池提高扫描效率 with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: # 为每个端口创建检测任务 future_to_port = {executor.submit(check_port, host, port, timeout): port for port in ports} # 处理完成的任务 for future in concurrent.futures.as_completed(future_to_port): port = future_to_port[future] try: is_open = future.result() if is_open: open_ports.append(port) except Exception as e: print(f"端口 {port} 扫描出错: {e}") print("\n扫描完成!") print("-" * 50) print(f"开放端口列表: {sorted(open_ports)}") return open_ports # 扫描常用端口 common_ports = [21, 22, 23, 25, 53, 80, 110, 143, 443, 465, 587, 993, 995, 3306, 3389] scan_ports("www.yourdomain.com", common_ports)
代码说明:
- 使用线程池并发执行多个端口检测,显著提高效率
- 限制最大并发数避免对目标主机造成过大压力
- 收集并返回所有开放端口列表
- 扫描常见服务端口(可自定义端口列表)
完整端口扫描器代码
结合上述功能,创建一个功能完整的端口扫描工具:
import socket import concurrent.futures import time import argparse # 常用端口列表(可根据需要扩展) WELL_KNOWN_PORTS = { 20: "FTP-DATA", 21: "FTP", 22: "SSH", 23: "Telnet", 25: "SMTP", 53: "DNS", 67: "DHCP", 68: "DHCP", 80: "HTTP", 110: "POP3", 119: "NNTP", 123: "NTP", 143: "IMAP", 161: "SNMP", 194: "IRC", 443: "HTTPS", 465: "SMTPS", 587: "SMTP", 993: "IMAPS", 995: "POP3S", 1433: "MSSQL", 1521: "Oracle", 3306: "MySQL", 3389: "RDP", 5432: "PostgreSQL", 5900: "VNC", 6379: "Redis", 8080: "HTTP-Proxy" } def check_port(host, port, timeout=1.5): try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.settimeout(timeout) result = s.connect_ex((host, port)) return result == 0 except: return False def port_scan(host, ports, max_threads=200, timeout=1.5): open_ports = {} print(f"🚀 开始扫描主机: {host}") print(f"📋 扫描端口数量: {len(ports)}") print(f"⚡ 线程数: {max_threads}") print("-" * 60) start_time = time.time() with concurrent.futures.ThreadPoolExecutor(max_workers=max_threads) as executor: futures = {executor.submit(check_port, host, port, timeout): port for port in ports} for i, future in enumerate(concurrent.futures.as_completed(futures)): port = futures[future] try: if future.result(): service = WELL_KNOWN_PORTS.get(port, "Unknown") print(f"✅ 端口 {port}/TCP 开放 ({service})") open_ports[port] = service else: print(f"❌ 端口 {port}/TCP 关闭", end='\r') except Exception as e: print(f"⚠️ 端口 {port} 扫描出错: {e}") duration = time.time() - start_time print("\n" + "-" * 60) print(f"扫描完成! 耗时: {duration:.2f}秒") print(f"开放端口数量: {len(open_ports)}") if open_ports: print("\n开放端口列表:") print("-" * 30) for port, service in open_ports.items(): print(f"端口 {port}/TCP: {service}") return open_ports if __name__ == "__main__": # 设置命令行参数解析 parser = argparse.ArgumentParser(description="Python端口扫描器") parser.add_argument("host", help="目标主机名或IP地址") parser.add_argument("-p", "--ports", nargs="?", default="1-1024", help="端口范围 (默认: 1-1024), 或指定端口列表,如:80,443,8080") parser.add_argument("-t", "--threads", type=int, default=200, help="最大线程数 (默认: 200)") parser.add_argument("-T", "--timeout", type=float, default=1.5, help="连接超时时间(秒) (默认: 1.5)") args = parser.parse_args() # 处理端口范围 ports = [] if ',' in args.ports: # 逗号分隔的端口列表 ports = [int(p.strip()) for p in args.ports.split(',')] elif '-' in args.ports: # 端口范围 start, end = map(int, args.ports.split('-')) ports = list(range(start, end + 1)) else: # 单个端口 ports = [int(args.ports)] # 执行扫描 port_scan(args.host, ports, args.threads, args.timeout)
功能特点:
- 支持命令行参数:目标主机、端口范围、线程数、超时时间
- 智能端口范围解析(支持单个端口、端口列表和端口范围)
- 显示端口对应的常见服务
- 实时扫描进度显示
- 详细扫描结果报告
- 多线程并发提高效率
使用示例:
将代码保存为port_scanner.py
后:
# 扫描常用端口 python port_scanner.py www.example.com # 扫描指定端口范围 python port_scanner.py 192.168.1.1 -p 20-100 # 扫描特定端口 python port_scanner.py example.com -p 80,443,8080 # 使用500线程扫描 python port_scanner.py target.com -p 1-65535 -t 500
应用场景与注意事项
典型应用场景:
- 服务器管理员检查服务端口状态
- 网络安全人员评估系统安全性
- 开发人员调试网络应用程序
- 监控系统定期检查服务可用性
重要注意事项:
- ⚠️ 仅扫描你有权限测试的主机
- ⚠️ 未经授权扫描他人网络可能违法
- ⚠️ 避免对目标主机发起过多并发连接(建议不超过500线程)
- ✅ 适当调整超时时间以平衡准确性和效率
- ✅ 使用已知端口字典可以更好地识别服务
- ✅ 考虑添加日志记录功能以便长期监控
可能的扩展方向:
- 添加UDP端口扫描支持
- 实现服务指纹识别(banner grabbing)
- 添加图形用户界面(GUI)
- 集成到监控系统中定期执行
- 添加电子邮件/短信通知功能
总结
Python的socket模块为端口检测提供了强大而灵活的基础功能。通过本教程,你学会了:
- 使用socket模块检测单个端口状态
- 利用多线程实现高效端口扫描
- 构建功能完整的命令行端口扫描工具
- 理解端口扫描的应用场景和注意事项
这些技能对于网络管理、安全评估和系统监控都非常有价值。请始终遵守法律法规,合理使用这些技术。
本文由LiangWaiDou于2025-07-29发表在吾爱品聚,如有疑问,请联系我们。
本文链接:https://521pj.cn/20256758.html
发表评论