Python多线程TCP端口扫描器实现详解
本文介绍如何使用Python3结合socket和threading库实现简易的多线程TCP端口扫描器。通过多线程技术显著加速对目标主机开放端口的检测过程,代码包含完整的端口扫描逻辑与测试示例,适合初学者理解并发网络编程基础。
Python多线程端口扫描器实现原理
本文展示一个基于Python3编写的简易TCP端口扫描程序。
主要需求是扫描指定目标网站或IP地址,找出所有处于开放状态的端口,并将结果输出。
原理分析:程序利用socket模块建立TCP连接。若连接成功建立,则判定该端口为开放状态;若连接失败,则默认判定为关闭。需要注意的是,部分端口可能因防火墙策略或网络波动导致连接失败,但实际处于开放状态,本程序对此类情况不做特殊处理,简单视为关闭。
实现该功能主要依赖两个标准库:socket用于网络通信,threading用于多线程处理。
具体实现步骤如下:
首先定义一个核心扫描函数,该函数接收IP地址和端口号作为参数,尝试建立TCP连接以判断端口状态。
def tcpPortScan(ip, port, openPort):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建套接字
sock.settimeout(0.1) # 设置延时时间
try:
result = sock.connect_ex((ip, port))
if result == 0: # 如果连接成功,返回值为0
openPort.append(port) # 如果端口开放,就把端口port赋给openPort
except:
pass
sock.close() # 关闭套接字
如果逐个串行调用上述扫描函数来检查目标地址的多个端口,效率会非常低。因此,引入多线程机制来并行执行扫描任务,从而大幅提升扫描速度。
接着定义一个多线程调度函数,负责创建、启动并等待所有线程执行完毕,以完成批量端口的扫描。
def threadingPortScan(host, portList, openPorts = []):
hostIP = socket.gethostbyname(host) # 获取域名对应的IP地址
nloops = range(len(portList))
threads = []
for i in nloops:
t = threading.Thread(target=tcpPortScan, args=(hostIP, portList[i], openPorts))
threads.append(t)
for i in nloops:
threads[i].start()
for i in nloops:
threads[i].join()
return openPorts # 返回值为该域名下开放的端口列表
以下是完整的Python源代码:
完整代码解析与测试
# -*- coding:utf-8 -*-
'''
使用多线程,检测一个目标地址的端口开放情况,目标地址由用户输入,端口暂时定义为0~1024,
检测TCP连接是否成功,如果连接成功,则端口开放,不成功则端口关闭
'''
import socket
import threading
def main():
host = input('please input domain:')
portList = range(0, 1025)
openPorts = threadingPortScan(host, portList)
print(host,'open ports:', openPorts)
# 对给定的(ip, port)进行TCP连接扫描
def tcpPortScan(ip, port, openPort):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建套接字
sock.settimeout(0.1) # 设置延时时间
try:
result = sock.connect_ex((ip, port))
if result == 0:
openPort.append(port) # 如果端口开放,就把端口port赋给openPort
except:
pass
sock.close() # 关闭套接字
def threadingPortScan(host, portList, openPorts = []):
hostIP = socket.gethostbyname(host) # 获取域名对应的IP地址
nloops = range(len(portList))
threads = []
for i in nloops:
t = threading.Thread(target=tcpPortScan, args=(hostIP, portList[i], openPorts))
threads.append(t)
for i in nloops:
threads[i].start()
for i in nloops:
threads[i].join()
return openPorts # 返回值为该域名下开放的端口列表
if __name__ == '__main__':
main()
以域名www.qq.com为例进行实际测试,运行结果如下所示:
>>>please input domain: www.qq.com
www.qq.com open ports: [80, 843]
总结而言,该程序仅适合初学者用于练习Python网络编程与多线程概念,并不适用于生产环境或专业安全测试。由于该简易扫描器未处理防火墙拦截、NAT转换或复杂网络策略,可能导致部分实际开放的端口被误判为关闭。
以上就是本文的全部内容,希望对读者的学习有所帮助,也欢迎大家继续支持本站获取更多技术资源。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













