☰
Python 实现简易端口扫描器,手把手代码讲解
2026/10/8 7:09:04 网站建设 项目流程

Python 实现简易端口扫描器,手把手代码讲解

前言

在网络安全、渗透测试、内网资产梳理、安全运维工作中,端口扫描是最基础、最核心的前置操作。无论是红蓝对抗内网打点、企业资产巡检、漏洞前期信息收集,还是个人学习网络编程,端口扫描都是必须掌握的核心技能。

日常工作中,绝大多数安全从业者都会使用 Nmap、Masscan、Zmap 等成熟开源扫描工具,这些工具性能极强、功能全面、支持多种扫描模式、服务版本探测、操作系统识别、漏洞探测。但只会使用工具、不懂底层原理,是很多安全初学者的通病:遇到扫描误报、防火墙拦截、环境适配问题、自定义扫描需求时完全无从下手。

Python 作为网络安全领域的首选编程语言,依托内置的socket网络套接字库、threading多线程库,可以从零手写一款属于自己的 TCP 端口扫描器。手写扫描器的核心价值,不在于替代 Nmap,而是彻底搞懂端口扫描底层逻辑、TCP 连接原理、并发扫描机制、网络超时适配。

本文将从网络基础原理、端口扫描分类、单线程零基础实现、多线程高性能优化、命令行参数封装、服务识别、性能调优、报错修复、实战避坑、源码拓展、面试考点全方位讲解,手把手带你从零编写、逐行解析、落地实战,适合零基础入门、安全面试复习、Python 网络编程学习。

⚠️法律免责声明
本文所有代码、技术原理、扫描方法仅可用于个人靶场学习、授权企业资产巡检、合规安全测试。严禁未经授权扫描公网服务器、内网业务资产、第三方设备。未经授权的网络扫描、探测行为违反《中华人民共和国网络安全法》,一切违规操作的法律责任由使用者自行承担。

一、前置基础:彻底搞懂端口与端口扫描原理

1.1 什么是端口?

计算机主机依靠IP 地址定位网络中的唯一设备,依靠端口(Port)定位设备内的具体服务进程。

一台主机拥有 65535 个可用 TCP 端口(1~65535),不同端口对应不同服务:

  • 21 端口:FTP 文件传输服务
  • 22 端口:SSH 远程连接服务(Linux 服务器核心端口)
  • 80 端口:HTTP 明文 Web 服务
  • 443 端口:HTTPS 加密 Web 服务
  • 3389 端口:Windows RDP 远程桌面
  • 3306 端口:MySQL 数据库服务
  • 6379 端口:Redis 缓存服务
  • 8080 端口:代理 / 后端 Web 服务

端口状态分为三种:

  1. 开放(Open):端口监听正常,可建立 TCP 连接,对外提供服务;
  2. 关闭(Closed):无进程监听该端口,无法建立连接;
  3. 过滤(Filtered):被防火墙、安全组拦截,无法判断端口真实状态(常见于公网服务器)。

1.2 常见端口扫描方式对比

主流端口扫描分为三类,本文实现最通用、最适合新手的TCP 全连接扫描:

1)TCP 全连接扫描(本文实现)

原理:完整完成TCP 三次握手,成功握手则判定端口开放。

  • 优点:代码简单、无需管理员权限、兼容性极强、无系统限制;
  • 缺点:会产生完整访问日志,极易被防火墙、EDR、WAF 检测拦截,隐蔽性差;
  • 适用场景:内网靶场学习、授权资产巡检、原理学习。
2)SYN 半连接扫描(Nmap 默认扫描)

原理:只发送 SYN 握手包,不完成三次握手,不建立完整连接。

  • 优点:隐蔽性高、无日志残留、扫描速度快;
  • 缺点:需要系统管理员权限、依赖底层网卡驱动,普通 Python 脚本无法实现。
3)UDP 扫描

针对 UDP 无连接协议扫描,多用于探测 DNS、SNMP 服务,日常渗透使用较少。

1.3 Python 核心依赖库讲解

本文所有代码无需第三方安装,全部使用 Python 内置标准库,兼容性拉满:

  1. socket:核心网络库,实现 TCP/UDP 套接字创建、连接请求、网络通信;
  2. threading:多线程库,解决单线程扫描速度慢的问题;
  3. time:计时、延时控制,统计扫描耗时、控制线程并发;
  4. argparse:命令行参数解析,实现工具化调用,无需修改源码。

二、入门版:单线程端口扫描器(零基础必学)

2.1 完整源码

这是最基础的版本,无复杂逻辑、无并发、纯原生 TCP 连接探测,适合新手理解核心原理。

# 单线程简易端口扫描器(入门版) import socket # 定义单端口扫描函数 def scan_single_port(target_ip, port): # 创建IPv4、TCP流式套接字 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置连接超时时间,避免程序卡死 sock.settimeout(0.5) try: # 尝试建立TCP连接,返回状态码 connect_status = sock.connect_ex((target_ip, port)) # connect_status == 0 代表连接成功,端口开放 if connect_status == 0: print(f"[✅ 开放] 目标IP:{target_ip} 端口:{port}") except Exception as e: # 捕获异常,静默处理超时、拒绝连接等错误 pass finally: # 强制关闭套接字,释放系统资源 sock.close() # 主程序入口 if __name__ == "__main__": # 自定义扫描目标与端口范围 target = "192.168.1.100" start_port = 1 end_port = 100 print("===== 单线程端口扫描开始 =====") # 遍历端口逐个扫描 for port in range(start_port, end_port + 1): scan_single_port(target, port) print("===== 端口扫描完成 =====")

2.2 逐行超详细代码解析

  1. socket.AF_INET:指定使用 IPv4 网络协议,是目前主流网络协议;
  2. socket.SOCK_STREAM:指定使用 TCP 流式传输协议,稳定可靠、面向连接;
  3. sock.settimeout(0.5):核心配置,设置 0.5 秒超时。网络扫描存在延迟,若不设置超时,程序会无限卡死等待;
  4. connect_ex()核心函数
    • 区别于connect()函数:不会抛出异常,仅返回数字状态码;
    • 返回 0:TCP 连接成功,端口开放;
    • 返回非 0:端口关闭 / 防火墙拦截 / 连接超时;
  5. finally 关闭套接字:网络套接字属于系统资源,不主动关闭会造成资源泄露,大量扫描后程序卡顿崩溃。

2.3 单线程版本优缺点

✅ 优点:代码极简、逻辑清晰、零报错、新手友好、极易理解 TCP 扫描原理;
❌ 缺点:串行扫描、速度极慢,1-1000 端口需要数分钟,无法用于实际批量扫描。

三、进阶版:多线程高性能端口扫描器(实用主力版)

为了解决单线程扫描速度慢的问题,我们引入多线程并发扫描,同时新增服务识别、线程限流、扫描计时、结果汇总、线程锁等核心功能,也是日常学习、靶场实战的主力版本。

3.1 完整优化源码

# 多线程高性能端口扫描器(进阶完整版) import socket import threading import time # 全局存储开放端口与对应服务 open_port_list = [] # 线程锁:解决多线程数据竞争问题 thread_lock = threading.Lock() # 常用端口-服务映射库(可自行无限拓展) PORT_SERVICE_MAP = { 21: "FTP文件传输服务", 22: "SSH远程连接服务", 23: "Telnet远程登录服务", 25: "SMTP邮件发送服务", 53: "DNS域名解析服务", 80: "HTTP网页服务", 110: "POP3邮件接收服务", 135: "RPC远程过程调用服务", 139: "NetBIOS局域网共享服务", 443: "HTTPS加密网页服务", 445: "SMB文件共享服务(高危)", 3306: "MySQL数据库服务", 3389: "RDP远程桌面服务(高危)", 6379: "Redis缓存数据库服务", 8080: "HTTP代理/后端服务", 8090: "后台管理服务", 9000: "端口转发/应用服务" } def port_scan_func(target_ip, port): """单端口扫描核心函数""" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(0.4) try: # 尝试TCP连接 res = sock.connect_ex((target_ip, port)) if res == 0: # 匹配端口对应的服务,未知服务显示Unknown service_name = PORT_SERVICE_MAP.get(port, "未知自定义服务") # 加锁:保证多线程写入数据不混乱 with thread_lock: open_port_list.append({"port": port, "service": service_name}) print(f"[+] 端口开放 | {port} | 服务:{service_name}") except: pass finally: sock.close() def multi_thread_scan(target_ip, start, end, max_thread=60): """多线程扫描主函数""" print("=" * 60) print(f"【扫描配置信息】") print(f"扫描目标IP:{target_ip}") print(f"扫描端口范围:{start} ~ {end}") print(f"最大并发线程:{max_thread}") print("=" * 60) # 记录扫描开始时间 start_time = time.time() thread_pool = [] # 遍历所有端口,创建扫描线程 for port in range(start, end + 1): thread = threading.Thread(target=port_scan_func, args=(target_ip, port)) thread_pool.append(thread) thread.start() # 线程限流:防止并发过高导致本机网络卡死、丢包误报 while len(threading.enumerate()) > max_thread: time.sleep(0.01) # 阻塞主线程,等待所有子线程执行完毕 for t in thread_pool: t.join() # 计算扫描总耗时 end_time = time.time() total_time = round(end_time - start_time, 2) # 扫描结果汇总输出 print("\n" + "=" * 60) print(f"扫描完成!总耗时:{total_time} 秒") if open_port_list: print(f"共探测到 {len(open_port_list)} 个开放端口:") for info in open_port_list: print(f"✅ {info['port']} 端口 - {info['service']}") else: print("❌ 未探测到任何开放端口") print("=" * 60) if __name__ == "__main__": # 自定义扫描参数 scan_ip = "192.168.1.100" multi_thread_scan(target_ip=scan_ip, start=1, end=1000, max_thread=60)

3.2 核心新增功能深度解析

1)线程锁(thread_lock)

多线程同时操作全局列表时,会出现数据竞争、数据丢失、列表错乱的问题。
threading.Lock()可以保证同一时间只有一个线程写入数据,完美解决并发数据错乱问题,是多线程开发的核心知识点。

2)线程限流机制

如果无限制创建线程,一次性生成 1000+ 线程,会耗尽本机网络资源、CPU 资源,导致端口误判、程序崩溃、网络卡顿。
通过len(threading.enumerate())实时监控运行线程数,严格限制最大并发,兼顾扫描速度与稳定性。

3)服务自动识别

内置常用端口服务映射表,扫描到开放端口自动匹配服务名称,不用手动查表,实现可视化资产识别。

4)精准计时 + 结果汇总

自动统计扫描总耗时,扫描结束后统一汇总所有开放端口,避免日志杂乱,结果清晰直观。

四、终极工具版:命令行参数端口扫描器(可直接当工具用)

前面的版本需要修改源码更换 IP、端口、线程数,不够便捷。我们基于argparse实现命令行参数调用,无需改代码,终端直接传参,完全对标商业化扫描工具。

4.1 最终完整源码

# Python 命令行端口扫描器(终极工具版) import socket import threading import time import argparse # 全局变量与线程锁 open_port_list = [] thread_lock = threading.Lock() # 端口服务映射字典 PORT_SERVICE_MAP = { 21: "FTP文件传输服务", 22: "SSH远程连接服务", 23: "Telnet远程登录服务", 25: "SMTP邮件发送服务", 53: "DNS域名解析服务", 80: "HTTP网页服务", 110: "POP3邮件接收服务", 135: "RPC远程过程调用服务", 139: "NetBIOS局域网共享服务", 443: "HTTPS加密网页服务", 445: "SMB文件共享服务(高危)", 3306: "MySQL数据库服务", 3389: "RDP远程桌面服务(高危)", 6379: "Redis缓存数据库服务", 8080: "HTTP代理/后端服务", 8090: "后台管理服务", 9000: "端口转发/应用服务" } def port_scan_func(target_ip, port): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(0.4) try: res = sock.connect_ex((target_ip, port)) if res == 0: service_name = PORT_SERVICE_MAP.get(port, "未知自定义服务") with thread_lock: open_port_list.append({"port": port, "service": service_name}) print(f"[+] 端口开放 | {port:5d} | 服务:{service_name}") except: pass finally: sock.close() def multi_thread_scan(target_ip, start_port, end_port, max_thread): print("=" * 60) print(f"【Python高性能端口扫描器】") print(f"扫描目标IP:{target_ip}") print(f"扫描端口范围:{start_port} ~ {end_port}") print(f"最大并发线程:{max_thread}") print("=" * 60) start_time = time.time() thread_pool = [] for port in range(start_port, end_port + 1): t = threading.Thread(target=port_scan_func, args=(target_ip, port)) thread_pool.append(t) t.start() while len(threading.enumerate()) > max_thread: time.sleep(0.01) for t in thread_pool: t.join() end_time = time.time() total_time = round(end_time - start_time, 2) print("\n" + "=" * 60) print(f"扫描完成!总耗时:{total_time} 秒") if open_port_list: print(f"共探测到 {len(open_port_list)} 个开放端口:") for info in open_port_list: print(f"✅ {info['port']} 端口 - {info['service']}") else: print("❌ 未探测到任何开放端口") print("=" * 60) if __name__ == "__main__": # 初始化命令行参数解析器 parser = argparse.ArgumentParser(description="Python 多线程TCP端口扫描工具 | 内网资产探测专用") parser.add_argument("-i", "--ip", required=True, help="必填:目标IP地址,例:192.168.1.100") parser.add_argument("-s", "--start", type=int, default=1, help="可选:起始端口,默认1") parser.add_argument("-e", "--end", type=int, default=1000, help="可选:结束端口,默认1000") parser.add_argument("-t", "--thread", type=int, default=60, help="可选:最大并发线程,默认60") # 解析参数 args = parser.parse_args() # 执行扫描 multi_thread_scan(args.ip, args.start, args.end, args.thread)

4.2 工具使用教程

将代码保存为port_scan.py,打开终端 / CMD,即可灵活调用:

# 基础用法:扫描1-1000端口,默认60线程 python port_scan.py -i 192.168.1.100 # 自定义端口范围:扫描1-500端口 python port_scan.py -i 192.168.1.100 -s 1 -e 500 # 自定义线程数:100线程高速扫描 python port_scan.py -i 192.168.1.100 -t 100 # 全端口扫描(1-65535) python port_scan.py -i 192.168.1.100 -s 1 -e 65535

五、关键参数调优与实战避坑指南

5.1 超时时间调优(核心避坑)

  • 内网扫描:延迟低,设置0.3~0.4s,速度最快、准确率最高;
  • 跨网段 / 公网扫描:延迟高,设置0.8~1s,避免误判关闭;
  • 超时过小:漏报(开放端口判定为关闭);
  • 超时过大:扫描速度变慢。

5.2 线程数调优

  • 家用电脑 / 虚拟机:50-80 线程最佳,不卡顿、无丢包;
  • 高配服务器:可设置 100-150 线程;
  • 禁止 200 线程以上:极易触发系统网络限制、防火墙拦截,导致扫描失效。

5.3 常见报错与解决方案

  1. 端口扫描全部无结果
    排查:目标主机防火墙开启、IP 不通、网络不通,先 ping 测试连通性;
  2. 程序运行卡顿卡死
    排查:无线程限流、线程数过高,降低并发、增加延时;
  3. 部分开放端口扫不出来
    排查:超时时间太短,适当延长超时时间。

六、本扫描器优缺点 & 面试高频考点

6.1 优点

  1. 纯原生库、零依赖、跨平台(Windows/Linux/Mac 通用);
  2. 多线程并发,扫描速度远超单线程脚本;
  3. 带服务识别、结果汇总、命令行调用,实用性极强;
  4. 代码简洁、无加密、易二次开发、适合学习。

6.2 局限性(面试必答)

  1. TCP 全连接扫描,隐蔽性差,会留下完整日志,易被安全设备拦截;
  2. 仅支持 TCP 扫描,不支持 UDP、SYN 扫描;
  3. 无服务版本探测、无操作系统识别、无漏洞检测;
  4. 公网扫描误报率高,易被防火墙拦截。

6.3 面试高频问题

  1. 单线程和多线程端口扫描的区别?
  2. TCP 全连接扫描和 SYN 半连接扫描的差异?
  3. 多线程扫描为什么需要加线程锁?
  4. 端口扫描超时时间设置的意义?

七、二次开发拓展功能(进阶学习方向)

学完基础版本后,可自行拓展以下实战功能,打造专属扫描工具:

  1. 域名解析扫描:支持输入域名自动解析 IP 扫描;
  2. C 段网段扫描:批量扫描 192.168.1.1-192.168.1.254 整段主机;
  3. Banner 版本抓取:获取服务版本(Nginx、Apache、SSH 版本);
  4. 结果导出:自动将扫描结果保存为 TXT/CSV 报告;
  5. 存活主机探测:先 ping 探测主机是否存活,再扫描端口,提升效率;
  6. 进度条显示:实时展示扫描进度。

八、学习总结

本文从零讲解了端口扫描的网络原理、TCP 连接机制、单线程基础实现、多线程高性能优化、工具化封装、参数调优、实战避坑、面试考点。

手写端口扫描器的核心目的不是替代 Nmap,而是吃透网络编程底层、理解端口探测逻辑、掌握多线程并发开发能力。在安全面试、内网实战、Python 安全开发中,这套原理都是核心加分项。

日常合规实战中,推荐手写脚本用于原理学习、内网巡检,正式渗透测试、资产探测优先使用 Nmap、Masscan 等专业工具。


最后

关于网络安全技术储备

学好网络安全不论是就业还是做副业赚钱都不错,但要学会网络安全还是要有一个学习规划。最后大家分享一份全套的网络安全学习资料,给那些想学习网络安全的小伙伴们一点帮助!

对于0基础小白入门:

如果你是零基础小白,想快速入门网络安全是可以考虑的。

一方面是学习时间相对较短,学习内容更全面更集中。

二方面是可以找到适合自己的学习方案

包括:网安成长学习路线图、SRC&黑客文档、护网行动、黑客必读书单、面试题、学习视频等教程。带你从零基础系统性的学好网络安全!

需要的可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

👉1.成长路线图&学习规划👈
要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

👉2.网安入门到进阶视频教程👈
很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩。(全套教程文末领取哈)

👉3.SRC&黑客文档👈
大家最喜欢也是最关心的SRC技术文籍&黑客技术也有收录

SRC技术文籍:

黑客资料由于是敏感资源,这里不能直接展示哦!(全套教程文末领取哈)

👉4.护网行动资料👈
其中关于HW护网行动,也准备了对应的资料,这些内容可相当于比赛的金手指!

👉5.黑客必读书单👈

随着互联网技术的飞速发展,网络安全已经成为了当今科技领域的一大热点。这些SQL注入、CCNA、Web渗透、Linux服务器等,以其强大的语言理解和防御能力,正在守护着我们网络世界。 那以下这些PDF籍就是非常不错的学习资源。

👉6.网络安全岗面试题合集👈
当你自学到这里,你就要开始思考找工作的事情了,而工作绕不开的就是真题和面试题。

这份完整版的网络安全学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询