基于Python開(kāi)發(fā)一個(gè)多線程IP網(wǎng)絡(luò)掃描工具
項(xiàng)目簡(jiǎn)介
IP Scanner 是一個(gè)基于 Python 開(kāi)發(fā)的網(wǎng)絡(luò)掃描工具,它能夠快速掃描指定網(wǎng)段內(nèi)的活動(dòng) IP 地址。該工具采用多線程技術(shù)提高掃描效率,并提供了友好的圖形用戶(hù)界面,支持中英文界面切換。

技術(shù)棧
核心技術(shù)
- Python 3.x: 主要開(kāi)發(fā)語(yǔ)言
- tkinter: GUI界面開(kāi)發(fā)
- threading: 多線程支持
- concurrent.futures: 線程池管理
- subprocess: 系統(tǒng)命令調(diào)用
- queue: 線程間通信
- json: 配置文件管理
依賴(lài)庫(kù)
pyinstaller # 用于打包可執(zhí)行文件 requests # 網(wǎng)絡(luò)請(qǐng)求支持
主要功能
1.網(wǎng)段掃描
- 支持自定義網(wǎng)段輸入(如192.168.1)
- 使用ping命令檢測(cè)IP地址活動(dòng)狀態(tài)
- 多線程并發(fā)掃描,最大支持50個(gè)線程
2.實(shí)時(shí)進(jìn)度顯示
- 進(jìn)度條顯示當(dāng)前掃描進(jìn)度
- 實(shí)時(shí)顯示正在掃描的IP地址
- 即時(shí)展示發(fā)現(xiàn)的活動(dòng)IP
3.國(guó)際化支持
- 支持中英文界面切換
- 自動(dòng)保存語(yǔ)言偏好設(shè)置
- 基于用戶(hù)系統(tǒng)語(yǔ)言自動(dòng)選擇默認(rèn)語(yǔ)言
4.用戶(hù)友好界面
- 清晰的掃描控制(開(kāi)始/停止)
- 結(jié)果區(qū)域支持滾動(dòng)顯示
- 一鍵訪問(wèn)項(xiàng)目GitHub頁(yè)面
核心代碼實(shí)現(xiàn)
主程序代碼 (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" # 默認(rèn)網(wǎng)段
self.thread_pool = ThreadPoolExecutor(max_workers=50) # 創(chuàng)建線程池,最大50個(gè)線程
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 # 停止當(dāng)前掃描
self.network_segment = segment
self.result_queue = queue.Queue() # 清空結(jié)果隊(duì)列
self.current_ip_queue = queue.Queue() # 清空進(jìn)度隊(duì)列
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))
# 等待所有任務(wù)完成
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')
# 多語(yǔ)言文本
self.texts = {
'zh': {
'title': 'IP掃描器',
'status_ready': '準(zhǔn)備掃描...',
'network_label': '網(wǎng)段:',
'start_button': '開(kāi)始掃描',
'stop_button': '停止掃描',
'result_frame': '掃描結(jié)果',
'error_empty': '請(qǐng)輸入網(wǎng)段!',
'scanning': '正在掃描: {ip}',
'scan_complete': '掃描完成',
'found_ip': '發(fā)現(xiàn)活動(dòng)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
# 創(chuàng)建界面元素
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')
# 狀態(tài)標(biāo)簽
self.status_label = ttk.Label(self.root, text=self.texts[self.language]['status_ready'])
self.status_label.pack(pady=5)
# 網(wǎng)段輸入框
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)
# 進(jìn)度條
self.progress = ttk.Progressbar(self.root, mode='determinate')
self.progress.pack(pady=10, padx=10, fill='x')
# 結(jié)果顯示區(qū)域
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)
# 滾動(dòng)條
scrollbar = ttk.Scrollbar(result_frame, command=self.result_text.yview)
scrollbar.pack(side='right', fill='y')
self.result_text.configure(yscrollcommand=scrollbar.set)
# GitHub鏈接標(biāo)簽
github_frame = ttk.Frame(self.root)
github_frame.pack(side='bottom', pady=5)
# 語(yǔ)言切換按鈕
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):
# 獲取并設(shè)置網(wǎng)段
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'
# 啟動(dòng)掃描線程
self.scan_thread = threading.Thread(target=self.scan_process)
self.scan_thread.start()
# 啟動(dòng)更新界面的線程
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
# 更新當(dāng)前掃描的IP和進(jìn)度條
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
# 檢查并顯示結(jié)果
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()
項(xiàng)目特點(diǎn)
1.高效性能
- 采用ThreadPoolExecutor管理線程池
- 最大支持50個(gè)并發(fā)線程
- 異步更新UI,避免界面卡頓
2.可靠性
- 完善的異常處理機(jī)制
- 支持掃描過(guò)程中斷
- 配置持久化存儲(chǔ)
3.可擴(kuò)展性
- 模塊化的代碼結(jié)構(gòu)
- 清晰的類(lèi)層次設(shè)計(jì)
- 易于添加新功能
項(xiàng)目地址
GitHub: github.com/dependon/ip_scanner
使用說(shuō)明
- 在輸入框中輸入要掃描的網(wǎng)段(如192.168.1)
- 點(diǎn)擊"開(kāi)始掃描"按鈕開(kāi)始掃描
- 掃描過(guò)程中可以通過(guò)"停止掃描"按鈕隨時(shí)中斷
- 活動(dòng)IP地址將實(shí)時(shí)顯示在結(jié)果區(qū)域
- 可通過(guò)語(yǔ)言切換按鈕切換中英文界面
安裝部署
安裝依賴(lài):
pip install -r requirements.txt
運(yùn)行程序:
python ip_scanner.py
打包可執(zhí)行文件:
pyinstaller -F ip_scanner.py
總結(jié)
IP Scanner是一個(gè)功能完整、性能優(yōu)秀的網(wǎng)絡(luò)掃描工具,它不僅實(shí)現(xiàn)了基本的IP掃描功能,還提供了友好的用戶(hù)界面和多語(yǔ)言支持。通過(guò)多線程技術(shù)的應(yīng)用,大大提高了掃描效率。項(xiàng)目代碼結(jié)構(gòu)清晰,易于維護(hù)和擴(kuò)展,是一個(gè)很好的Python GUI應(yīng)用開(kāi)發(fā)示例。
到此這篇關(guān)于基于Python開(kāi)發(fā)一個(gè)多線程IP網(wǎng)絡(luò)掃描工具的文章就介紹到這了,更多相關(guān)Python IP網(wǎng)絡(luò)掃描工具內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
對(duì)django xadmin自定義菜單的實(shí)例詳解
今天小編就為大家分享一篇對(duì)django xadmin自定義菜單的實(shí)例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
使用Django中的filter方法進(jìn)行數(shù)據(jù)查詢(xún)的基本操作
在 Django 中,QuerySet 的 filter() 方法是一個(gè)強(qiáng)大的工具,用于從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù)并根據(jù)指定的條件進(jìn)行篩選,在本文中,我們將介紹如何使用 filter() 方法來(lái)執(zhí)行各種類(lèi)型的數(shù)據(jù)查詢(xún)操作,需要的朋友可以參考下2024-05-05
解決django無(wú)法訪問(wèn)本地static文件(js,css,img)網(wǎng)頁(yè)里js,cs都加載不了
這篇文章主要介紹了解決django無(wú)法訪問(wèn)本地static文件(js,css,img)網(wǎng)頁(yè)里js,cs都加載不了的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
Python實(shí)現(xiàn)LZ77序列壓縮算法的原理與實(shí)戰(zhàn)指南
在眾多壓縮算法中,LZ77算法因其高效的重復(fù)模式識(shí)別能力而廣受歡迎,本文將詳細(xì)介紹如何使用Python實(shí)現(xiàn)一個(gè)基于LZ77的序列壓縮算法,并深入分析其工作原理和性能2025-10-10
Python利用PIL實(shí)現(xiàn)多張圖片合成gif動(dòng)畫(huà)的案例詳解
這篇文章主要介紹了Python利用PIL實(shí)現(xiàn)多張圖片合成gif動(dòng)畫(huà)的案例,文章通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴可以自己動(dòng)手試一下2023-11-11
Python natsort庫(kù)實(shí)現(xiàn)自然排序
本文介紹了Python的natsort庫(kù),該庫(kù)實(shí)現(xiàn)了自然排序功能,能夠智能識(shí)別字符串中的數(shù)字部分并按照數(shù)值大小進(jìn)行排序,感興趣的可以了解一下2026-01-01
python函數(shù)和python匿名函數(shù)lambda詳解
這篇文章主要介紹了python函數(shù)和python匿名函數(shù)lambda,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09
pyinstaller打包可執(zhí)行文件出現(xiàn)KeyError的問(wèn)題
這篇文章主要介紹了pyinstaller打包可執(zhí)行文件出現(xiàn)KeyError的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
Flask學(xué)習(xí)筆記之日志操作配置實(shí)例講解
這篇文章主要為大家介紹了Flask學(xué)習(xí)筆記之日志操作配置實(shí)例講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11

