IP Scanner - 多线程网络扫描工具

项目简介

IP Scanner 是一个基于 Python 开发的网络扫描工具,它能够快速扫描指定网段内的活动 IP 地址。该工具采用多线程技术提高扫描效率,并提供了友好的图形用户界面,支持中英文界面切换。

技术栈

核心技术

  • Python 3.x: 主要开发语言
  • tkinter: GUI界面开发
  • threading: 多线程支持
  • concurrent.futures: 线程池管理
  • subprocess: 系统命令调用
  • queue: 线程间通信
  • json: 配置文件管理

依赖库

pyinstaller  # 用于打包可执行文件
requests # 网络请求支持

主要功能

  1. 网段扫描

    • 支持自定义网段输入(如192.168.1)
    • 使用ping命令检测IP地址活动状态
    • 多线程并发扫描,最大支持50个线程
  2. 实时进度显示

    • 进度条显示当前扫描进度
    • 实时显示正在扫描的IP地址
    • 即时展示发现的活动IP
  3. 国际化支持

    • 支持中英文界面切换
    • 自动保存语言偏好设置
    • 基于用户系统语言自动选择默认语言
  4. 用户友好界面

    • 清晰的扫描控制(开始/停止)
    • 结果区域支持滚动显示
    • 一键访问项目GitHub页面

核心代码实现

主程序代码 (ip_scanner.py)

import os
import sys
import tkinter as tk
from tkinter import ttk, messagebox
import threading
import subprocess
import platform
import queue
import time
from concurrent.futures import ThreadPoolExecutor
import locale
import webbrowser
import json class IPScanner:
def __init__(self):
self.is_running = False
self.result_queue = queue.Queue()
self.current_ip_queue = queue.Queue()
self.network_segment = "192.168.2" # 默认网段
self.thread_pool = ThreadPoolExecutor(max_workers=50) # 创建线程池,最大50个线程 def ping(self, ip):
param = '-n' if platform.system().lower() == 'windows' else '-c'
command = ['ping', param, '1', ip]
try:
output = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=1)
return output.returncode == 0
except subprocess.TimeoutExpired:
return False def set_network_segment(self, segment):
self.is_running = False # 停止当前扫描
self.network_segment = segment
self.result_queue = queue.Queue() # 清空结果队列
self.current_ip_queue = queue.Queue() # 清空进度队列 def scan_ip(self, i, total):
if not self.is_running:
return
ip = f'{self.network_segment}.{i}'
self.current_ip_queue.put((ip, (i - 1) / total * 100))
if self.ping(ip):
self.result_queue.put(ip) def scan_range(self, start_ip, end_ip):
total = end_ip - start_ip + 1
futures = []
for i in range(start_ip, end_ip + 1):
if not self.is_running:
break
futures.append(self.thread_pool.submit(self.scan_ip, i, total)) # 等待所有任务完成
for future in futures:
future.result() class App:
def __init__(self, root):
self.root = root # 加载配置
self.config_file = 'ip_scanner_config.json'
self.language = self.load_config() or ('zh' if (locale.getlocale()[0] or locale.getdefaultlocale()[0]).startswith('zh') else 'en') # 多语言文本
self.texts = {
'zh': {
'title': 'IP扫描器',
'status_ready': '准备扫描...',
'network_label': '网段:',
'start_button': '开始扫描',
'stop_button': '停止扫描',
'result_frame': '扫描结果',
'error_empty': '请输入网段!',
'scanning': '正在扫描: {ip}',
'scan_complete': '扫描完成',
'found_ip': '发现活动IP: {ip}'
},
'en': {
'title': 'IP Scanner',
'status_ready': 'Ready to scan...',
'network_label': 'Network:',
'start_button': 'Start Scan',
'stop_button': 'Stop Scan',
'result_frame': 'Scan Results',
'error_empty': 'Please enter network segment!',
'scanning': 'Scanning: {ip}',
'scan_complete': 'Scan complete',
'found_ip': 'Active IP found: {ip}'
}
} self.root.title(self.texts[self.language]['title'])
self.root.geometry('400x500') self.scanner = IPScanner()
self.scan_thread = None # 创建界面元素
self.create_widgets() def load_config(self):
try:
with open(self.config_file, 'r') as f:
config = json.load(f)
return config.get('language')
except (FileNotFoundError, json.JSONDecodeError):
return None def save_config(self):
with open(self.config_file, 'w') as f:
json.dump({'language': self.language}, f) def switch_language(self):
self.language = 'en' if self.language == 'zh' else 'zh'
self.save_config()
# 重启程序 os.execv(sys.executable, ['python'] + sys.argv) def update_ui_text(self):
# 更新所有UI文本
self.status_label.config(text=self.texts[self.language]['status_ready'])
self.start_button.config(text=self.texts[self.language]['start_button'])
self.stop_button.config(text=self.texts[self.language]['stop_button'])
self.segment_frame.winfo_children()[0].config(text=self.texts[self.language]['network_label'])
self.result_frame.config(text=self.texts[self.language]['result_frame']) def create_widgets(self):
# 控制框架
control_frame = ttk.Frame(self.root)
control_frame.pack(pady=10, padx=10, fill='x') # 状态标签
self.status_label = ttk.Label(self.root, text=self.texts[self.language]['status_ready'])
self.status_label.pack(pady=5) # 网段输入框
segment_frame = ttk.Frame(control_frame)
segment_frame.pack(side='left', padx=5) ttk.Label(segment_frame, text=self.texts[self.language]['network_label']).pack(side='left')
self.segment_entry = ttk.Entry(segment_frame, width=15)
self.segment_entry.pack(side='left')
self.segment_entry.insert(0, '192.168.2') self.start_button = ttk.Button(control_frame, text=self.texts[self.language]['start_button'], command=self.start_scan)
self.start_button.pack(side='left', padx=5) self.stop_button = ttk.Button(control_frame, text=self.texts[self.language]['stop_button'], command=self.stop_scan, state='disabled')
self.stop_button.pack(side='left', padx=5) # 进度条
self.progress = ttk.Progressbar(self.root, mode='determinate')
self.progress.pack(pady=10, padx=10, fill='x') # 结果显示区域
result_frame = ttk.LabelFrame(self.root, text=self.texts[self.language]['result_frame'])
result_frame.pack(pady=10, padx=10, fill='both', expand=True) self.result_text = tk.Text(result_frame, height=15)
self.result_text.pack(pady=5, padx=5, fill='both', expand=True) # 滚动条
scrollbar = ttk.Scrollbar(result_frame, command=self.result_text.yview)
scrollbar.pack(side='right', fill='y')
self.result_text.configure(yscrollcommand=scrollbar.set) # GitHub链接标签
github_frame = ttk.Frame(self.root)
github_frame.pack(side='bottom', pady=5)
# 语言切换按钮
language_button = ttk.Button(github_frame, text="中文/English", command=self.switch_language)
language_button.pack(side='left', padx=5) github_label = ttk.Label(github_frame, text="GitHub: https://github.com/dependon/ip_scanner", cursor="hand2")
github_label.pack(side='left', padx=5)
github_label.bind("<Button-1>", lambda e: webbrowser.open("https://github.com/dependon/ip_scanner")) def start_scan(self):
# 获取并设置网段
network_segment = self.segment_entry.get().strip()
if not network_segment:
tk.messagebox.showerror(self.texts[self.language]['title'], self.texts[self.language]['error_empty'])
return self.scanner.set_network_segment(network_segment)
self.result_text.delete(1.0, tk.END)
self.progress['value'] = 0
self.scanner.is_running = True
self.start_button['state'] = 'disabled'
self.stop_button['state'] = 'normal' # 启动扫描线程
self.scan_thread = threading.Thread(target=self.scan_process)
self.scan_thread.start() # 启动更新界面的线程
self.update_ui() def stop_scan(self):
self.scanner.is_running = False
self.start_button['state'] = 'normal'
self.stop_button['state'] = 'disabled' def scan_process(self):
self.scanner.scan_range(1, 254) def update_ui(self):
if not self.scanner.is_running and self.scan_thread and not self.scan_thread.is_alive():
self.start_button['state'] = 'normal'
self.stop_button['state'] = 'disabled'
self.progress['value'] = 100
self.status_label.config(text=self.texts[self.language]['scan_complete'])
return # 更新当前扫描的IP和进度条
while not self.scanner.current_ip_queue.empty():
ip, progress = self.scanner.current_ip_queue.get()
self.status_label.config(text=self.texts[self.language]['scanning'].format(ip=ip))
self.progress['value'] = progress # 检查并显示结果
while not self.scanner.result_queue.empty():
ip = self.scanner.result_queue.get()
self.result_text.insert(tk.END, self.texts[self.language]['found_ip'].format(ip=ip)+'\n')
self.result_text.see(tk.END) self.root.after(100, self.update_ui) def main():
root = tk.Tk()
app = App(root)
root.mainloop() if __name__ == '__main__':
main()

项目特点

  1. 高效性能

    • 采用ThreadPoolExecutor管理线程池
    • 最大支持50个并发线程
    • 异步更新UI,避免界面卡顿
  2. 可靠性

    • 完善的异常处理机制
    • 支持扫描过程中断
    • 配置持久化存储
  3. 可扩展性

    • 模块化的代码结构
    • 清晰的类层次设计
    • 易于添加新功能

项目地址

使用说明

  1. 在输入框中输入要扫描的网段(如192.168.1)
  2. 点击"开始扫描"按钮开始扫描
  3. 扫描过程中可以通过"停止扫描"按钮随时中断
  4. 活动IP地址将实时显示在结果区域
  5. 可通过语言切换按钮切换中英文界面

安装部署

  1. 安装依赖:
pip install -r requirements.txt
  1. 运行程序:
python ip_scanner.py
  1. 打包可执行文件:
pyinstaller -F ip_scanner.py

总结

IP Scanner是一个功能完整、性能优秀的网络扫描工具,它不仅实现了基本的IP扫描功能,还提供了友好的用户界面和多语言支持。通过多线程技术的应用,大大提高了扫描效率。项目代码结构清晰,易于维护和扩展,是一个很好的Python GUI应用开发示例。

本文由博客一文多发平台 OpenWrite 发布!

AI写程序: 多线程网络扫描网段ip工具的更多相关文章

  1. Kail Linux渗透测试教程之网络扫描和嗅探工具Nmap

    Kail Linux渗透测试教程之网络扫描和嗅探工具Nmap 网络扫描和嗅探工具——Nmap Nmap也就网络映射器(Network Mapper),是一个免费开放的网络扫描和嗅探工具.该工具可以扫描 ...

  2. NMAP网络扫描工具的安装与使用

    简介 NMAP是一款流行的网络扫描和嗅探工具也是一个强大的端口扫描类安全测评工具,被广泛应用在黑客领域做漏洞探测以及安全扫描,更多的nmap是一个好用的网络工具,在生产和开发中也经常用到,主要做端口开 ...

  3. JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用

    JAVA之旅(三十二)--JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用 GUI写到一半电脑系统挂了,也就算了,最多GUI还有一个提示框和实例, ...

  4. 【转】网段,子网掩码,网络标识,IP划分

    网段指一个计算机网络中使用同一物理层设备(传输介质,中继器,集线器等)直接通讯的那一部分.就是从一个IP到另一个IP 好比 从192.168.0.1到192.168.255.255这之间就是一个网段 ...

  5. 【Socket】linux网络扫描程序开发

      1.mystery引入    1)系统入侵步骤:系统发现->漏洞探测->漏洞利用->痕迹清除    2)扫描器分类:主机与网络扫描器:端口服务扫描器:服务漏洞扫描器    3)T ...

  6. 用JAVA写一个多线程程序,写四个线程,其中二个对一个变量加1,另外二个对一个变量减1

    package com.ljn.base; /** * @author lijinnan * @date:2013-9-12 上午9:55:32 */ public class IncDecThrea ...

  7. 网络扫描工具nmap

    nmap一般就用来扫描主机是否在线(特别是扫描局域网内存活的机器).开放了哪些端口.其他的功能用的比较少,做渗透的人可能要了解的多些. 1.1 选项说明 nmap需要自行安装. shell> y ...

  8. 网络扫描信息收集基于(Windows)

    1.首先说明一下一款网络扫描工具,在之前的博客中我曾简要的写过关于Advance IP Scanner使用方法,最近要写网络扫描的工具,所以对这款工具做一个详细的功能细节上的介绍. 如下图  在输入框 ...

  9. 网络侦查与网络扫描-P201421410029

    中国人民公安大学 Chinese people’ public security university 网络对抗技术 实验报告   实验一 网络侦查与网络扫描     学生姓名 李政浩 年级 2014 ...

  10. 一文搞懂网络知识,IP、子网掩码、网关、DNS、端口号

    网络的基本概念 客户端:应用 C/S(客户端/服务器) B/S(浏览器/服务器) 服务器:为客户端提供服务.数据.资源的机器 请求:客户端向服务器索取数据 响应:服务器对客户端请求作出反应,一般是返回 ...

随机推荐

  1. Flink学习(十六) ProcessFunctionAPI(底层API)

    我们之前学习的转换算子是无法访问时间的时间戳信息和水位线信息的.而这些在一些应用场景下,极为重要,例如MapFunction这样的map转换算子就无法访问时间戳或者当前事件的事件时间. 基于此,Dat ...

  2. 什么是CPU?

    当你用手机刷短视频.用电脑玩游戏,或是使用智能手表查看健康数据时,这些设备的核心"大脑"--CPU(中央处理器)正在默默工作.它是现代计算设备的核心,但很多人对它一知半解.今天我们 ...

  3. Web前端入门第 7 问:HTML 标签不闭合、乱闭合、只有闭合标签有没有什么问题?

    HTML 标签语法遵循层级嵌套的树形结构,如果写出来的代码不是树形结构,浏览器会怎么渲染? 注意:以下截图都来源于 Chrome 浏览器,不同浏览器可能会产生不同的渲染结果. 先看正常代码 <s ...

  4. mac环境配置本地nfs服务

    前言 在这篇文章中,讲了在Mac端开启NFS服务,并通过NFS协议让其他设备挂载到你的Mac上. 步骤一:增加配置文件 首先,我们需要编辑NFS的配置文件,以便定义哪些目录可以被远程访问. 打开终端, ...

  5. 怎么给EXE文件加启动参数

    第一步 首先右键单击 exe 文件文件,创建 exe 文件的快捷方式. 第二步 右键单击此快捷方式--属性. 在快捷方式属性界面,点击目标后面的链接. 先打一个空格然后输入参数,然后点击应用按钮.确定 ...

  6. Go map字典排序

    前言 我们已经知道 Go 语言的字典是一个无序集合,如果你想要对字典进行排序,可以通过分别为字典的键和值创建切片,然后通过对切片进行排序来实现. 按照键进行排序 如果要对字典按照键进行排序,可以这么做 ...

  7. go sync.map的使用

    前言 数据竞争是并发情况下,存在多线程/协程读写相同数据的情况,必须存在至少一方写.另外,全是读的情况下是不存在数据竞争的. Go语言中的 map 在并发情况下,只读是线程安全的,同时读写是线程不安全 ...

  8. linux php重启

    1.停止命令 你可以先查看自己的php进程有没有启动 ps -ef | grep php [root@iZ6we4yxap93y2r0clg3g8Z ~]# ps -ef | grep php roo ...

  9. 使用 vscode-jest 插件

    vscode-jest [error] Abort jest session: Not able to auto detect a valid jest command: multiple candi ...

  10. CSS那些事读书笔记-2

    背景 作为一个后端开发,曾经尝试过学习前端,但是总觉不得要领,照猫画虎,而公司里又有专业的前端开发,工作中几乎接触不到实际的前端任务,所以前端的技能田野一直是一片荒芜.但是笔者深知前端的技能对找工作和 ...