上一篇
Python检测端口是否开放教程 - 简单高效的端口扫描方法
- Python
- 2025-07-29
- 1103
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发表在吾爱品聚,如有疑问,请联系我们。
本文链接:http://521pj.cn/20256758.html
发表评论