12
This commit is contained in:
@@ -234,3 +234,38 @@
|
|||||||
2025-10-31 14:33:40,697 [INFO] 停止由 Ping
|
2025-10-31 14:33:40,697 [INFO] 停止由 Ping
|
||||||
2025-10-31 14:49:43,147 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
2025-10-31 14:49:43,147 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
2025-10-31 14:49:48,110 [INFO] 停止Ping
|
2025-10-31 14:49:48,110 [INFO] 停止Ping
|
||||||
|
2025-10-31 14:58:38,388 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 14:59:33,663 [INFO] 开始Ping www.feixiangdayezhu.top
|
||||||
|
2025-10-31 14:59:36,241 [INFO] 停止Ping www.feixiangdayezhu.top
|
||||||
|
2025-10-31 14:59:39,525 [INFO] 开始由 Ping www.feixiangdayezhu.top
|
||||||
|
2025-10-31 14:59:42,345 [INFO] 停止由 Ping www.feixiangdayezhu.top
|
||||||
|
2025-10-31 15:01:36,902 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:02:00,585 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:03:20,413 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:04:37,391 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:05:43,467 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:06:28,952 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:07:24,602 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:08:36,439 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:09:05,633 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:11:01,416 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:11:41,046 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:11:54,147 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:11:55,877 [INFO] 开始由 Ping 127.0.0.1
|
||||||
|
2025-10-31 15:11:59,513 [INFO] 停止由 Ping 127.0.0.1
|
||||||
|
2025-10-31 15:12:01,021 [INFO] 开始由 Ping 127.0.0.1
|
||||||
|
2025-10-31 15:12:05,691 [INFO] 停止由 Ping 127.0.0.1
|
||||||
|
2025-10-31 15:31:50,086 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:32:43,390 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:33:36,375 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:40:33,765 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:41:13,921 [INFO] 开始由 Ping www.feixiangdayezhu.top
|
||||||
|
2025-10-31 15:41:20,661 [INFO] 停止由 Ping www.feixiangdayezhu.top
|
||||||
|
2025-10-31 15:51:03,844 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:51:22,946 [INFO] 开始由 Ping www.feixiangdayezhu.top
|
||||||
|
2025-10-31 15:51:26,928 [INFO] 停止由 Ping www.feixiangdayezhu.top
|
||||||
|
2025-10-31 15:56:35,413 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log
|
||||||
|
2025-10-31 15:56:41,068 [INFO] 开始批量 Ping 192.168.1.1 - 192.168.1.255
|
||||||
|
2025-10-31 15:57:02,030 [INFO] 开始由192.168.10.1 批量 Ping 192.168.1.1 - 192.168.1.255
|
||||||
|
2025-10-31 15:57:05,860 [INFO] 开始由192.168.10.1 批量 Ping 192.168.1.1 - 192.168.1.255
|
||||||
|
2025-10-31 15:57:06,885 [INFO] 停止由192.168.10.1 批量 Ping 192.168.1.1 - 192.168.1.255
|
||||||
|
|||||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import scrolledtext, messagebox
|
from tkinter import scrolledtext, messagebox
|
||||||
import subprocess
|
import subprocess
|
||||||
import platform
|
import concurrent.futures
|
||||||
import threading
|
import threading
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@@ -79,3 +79,73 @@ class PingFun:
|
|||||||
self.result_box.insert(tk.END, stats)
|
self.result_box.insert(tk.END, stats)
|
||||||
self.result_box.see(tk.END)
|
self.result_box.see(tk.END)
|
||||||
|
|
||||||
|
# ================= 批量 Ping =================
|
||||||
|
def start_batch_ping(self, net_prefix, start, end, local_ip=None, callback=None):
|
||||||
|
"""
|
||||||
|
批量 Ping 多个 IP 地址。
|
||||||
|
例如:net_prefix='192.168.1.' start=1 end=254
|
||||||
|
"""
|
||||||
|
self.callback = callback
|
||||||
|
self.stop_flag = False
|
||||||
|
self.result_box.delete('1.0', tk.END)
|
||||||
|
self.result_box.insert(tk.END, f"开始并发 Ping:{net_prefix}{start} - {net_prefix}{end}\n\n")
|
||||||
|
|
||||||
|
# ---- 启动线程池执行 ----
|
||||||
|
self.batch_thread = threading.Thread(
|
||||||
|
target=self._concurrent_batch_ping, args=(net_prefix, start, end, local_ip), daemon=True)
|
||||||
|
self.batch_thread.start()
|
||||||
|
|
||||||
|
def _ping_one_ip(self, ip, local_ip=None):
|
||||||
|
"""Ping 单个 IP 地址并返回结果"""
|
||||||
|
if self.stop_flag:
|
||||||
|
return None
|
||||||
|
|
||||||
|
command = ['ping', ip, '-n', '1', '-w', '1000']
|
||||||
|
if local_ip:
|
||||||
|
command += ['-S', local_ip]
|
||||||
|
try:
|
||||||
|
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
|
text=True, timeout=2)
|
||||||
|
if "TTL=" in result.stdout.upper():
|
||||||
|
return f"{ip} ✅ 通\n"
|
||||||
|
else:
|
||||||
|
return f"{ip} ❌ 不通\n"
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
return f"{ip} ⚠️ 超时\n"
|
||||||
|
except Exception as e:
|
||||||
|
return f"{ip} 错误: {e}\n"
|
||||||
|
|
||||||
|
def _concurrent_batch_ping(self, net_prefix, start, end, local_ip=None):
|
||||||
|
"""并发执行批量 Ping"""
|
||||||
|
ip_list = [f"{net_prefix}{i}" for i in range(start, end + 1)]
|
||||||
|
|
||||||
|
# 限制最大并发数,防止系统资源耗尽
|
||||||
|
max_workers = min(50, len(ip_list))
|
||||||
|
|
||||||
|
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
||||||
|
future_to_ip = {executor.submit(self._ping_one_ip, ip, local_ip): ip for ip in ip_list}
|
||||||
|
|
||||||
|
for future in concurrent.futures.as_completed(future_to_ip):
|
||||||
|
if self.stop_flag:
|
||||||
|
break
|
||||||
|
result = future.result()
|
||||||
|
if result:
|
||||||
|
self.result_box.insert(tk.END, result)
|
||||||
|
self.result_box.see(tk.END)
|
||||||
|
|
||||||
|
if not self.stop_flag:
|
||||||
|
self.result_box.insert(tk.END, "\n并发批量 Ping 完成。\n")
|
||||||
|
else:
|
||||||
|
self.result_box.insert(tk.END, "\n批量 Ping 已停止。\n")
|
||||||
|
self.result_box.see(tk.END)
|
||||||
|
if self.callback:
|
||||||
|
self.callback()
|
||||||
|
|
||||||
|
def stop_batch_ping(self):
|
||||||
|
"""停止并发批量 ping"""
|
||||||
|
if not self.batch_thread or not self.batch_thread.is_alive():
|
||||||
|
messagebox.showinfo("提示", "当前没有正在运行的批量 Ping。")
|
||||||
|
return
|
||||||
|
self.stop_flag = True
|
||||||
|
self.result_box.insert(tk.END, "\n正在尝试停止批量 Ping...\n")
|
||||||
|
self.result_box.see(tk.END)
|
||||||
Binary file not shown.
Binary file not shown.
+3
-3
@@ -88,7 +88,7 @@ class BasicUI:
|
|||||||
def add_button(
|
def add_button(
|
||||||
self, parent, button_text,
|
self, parent, button_text,
|
||||||
row, col=0, command="",
|
row, col=0, command="",
|
||||||
label_width=8, entry_width=20, colspan=1, sticky='w'
|
label_width=8, width=5, colspan=1, sticky='w'
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
添加一个按钮,并返回 (StringVar, Frame) 以便后续控制。
|
添加一个按钮,并返回 (StringVar, Frame) 以便后续控制。
|
||||||
@@ -96,14 +96,14 @@ class BasicUI:
|
|||||||
- button_text: 按钮文本
|
- button_text: 按钮文本
|
||||||
- row, col: 放置在父容器的 grid 行列
|
- row, col: 放置在父容器的 grid 行列
|
||||||
- command: 调用的函数
|
- command: 调用的函数
|
||||||
- entry_width: 输入框宽度
|
- width: 输入框宽度
|
||||||
- colspan: 该组控件在父容器上跨越的列数
|
- colspan: 该组控件在父容器上跨越的列数
|
||||||
- sticky: 对齐方式(默认左对齐)
|
- sticky: 对齐方式(默认左对齐)
|
||||||
"""
|
"""
|
||||||
group_frame = ttk.Frame(parent)
|
group_frame = ttk.Frame(parent)
|
||||||
group_frame.grid(row=row, column=col, columnspan=colspan, sticky=sticky, padx=5, pady=3)
|
group_frame.grid(row=row, column=col, columnspan=colspan, sticky=sticky, padx=5, pady=3)
|
||||||
|
|
||||||
btn = ttk.Button(group_frame, text=button_text, command=command)
|
btn = ttk.Button(group_frame, text=button_text, command=command, width=width)
|
||||||
btn.grid(row=0, column=0, sticky='w')
|
btn.grid(row=0, column=0, sticky='w')
|
||||||
return {
|
return {
|
||||||
"frame": group_frame,
|
"frame": group_frame,
|
||||||
|
|||||||
+65
-31
@@ -15,28 +15,31 @@ class PingTab(ttk.Frame, BasicUI):
|
|||||||
|
|
||||||
def ping_ui(self):
|
def ping_ui(self):
|
||||||
"""ping界面布局"""
|
"""ping界面布局"""
|
||||||
self.create_allIP_section()
|
|
||||||
self.create_assignIP_section()
|
self.create_assignIP_section()
|
||||||
|
self.create_batchIP_section()
|
||||||
self.create_outputping_section()
|
self.create_outputping_section()
|
||||||
# --------------------------------------UI界面布局函数--------------------------------------
|
# --------------------------------------UI界面布局函数--------------------------------------
|
||||||
def create_allIP_section(self):
|
|
||||||
# 区域标签
|
|
||||||
frame = ttk.LabelFrame(self, text="PING 目标IP")
|
|
||||||
frame.pack(side='top', fill='x', padx=10, pady=5)
|
|
||||||
|
|
||||||
self.entry_allIP = self.add_input(frame, "目标IP", row=0, col=0)
|
|
||||||
self.allIP_startPing = self.add_button(frame, "开始ping", row=0, col=1, command=self.btn_allIP_startPing)
|
|
||||||
self.allIP_stopPing = self.add_button(frame, "停止ping", row=0, col=2, command=self.btn_allIP_stopPing)
|
|
||||||
|
|
||||||
def create_assignIP_section(self):
|
def create_assignIP_section(self):
|
||||||
# 区域标签
|
# 区域标签
|
||||||
frame = ttk.LabelFrame(self, text="指定IP PING 目标IP")
|
frame = ttk.LabelFrame(self, text="指定地址 Ping 目标地址")
|
||||||
frame.pack(side='top', fill='x', padx=10, pady=5)
|
frame.pack(side='top', fill='x', padx=10, pady=5)
|
||||||
|
|
||||||
self.entry_assignIP_A = self.add_input(frame, "本地IP", row=0, col=0)
|
self.entry_assignIP_A = self.add_input(frame, "本地IP", row=0, col=0)
|
||||||
self.entry_assignIP_B = self.add_input(frame, "目标IP", row=0, col=1)
|
self.entry_assignIP_B = self.add_input(frame, "目标IP", row=0, col=1, inivar="127.0.0.1")
|
||||||
self.assignIP_startPing = self.add_button(frame, "开始ping", row=0, col=2, command=self.btn_assignIP_startPing)
|
self.assignIP_startPing = self.add_button(frame, "开始", row=0, col=2, command=self.btn_assignIP_startPing)
|
||||||
self.assignIP_stopPing = self.add_button(frame, "停止ping", row=0, col=3, command=self.btn_assignIP_stopPing)
|
self.assignIP_stopPing = self.add_button(frame, "停止", row=0, col=3, command=self.btn_assignIP_stopPing)
|
||||||
|
|
||||||
|
def create_batchIP_section(self):
|
||||||
|
# 区域标签
|
||||||
|
frame = ttk.LabelFrame(self, text="指定地址 Ping 批量地址")
|
||||||
|
frame.pack(side='top', fill='x', padx=10, pady=5)
|
||||||
|
|
||||||
|
self.entry_batchIP_A = self.add_input(frame, "本地IP", row=0, col=0)
|
||||||
|
self.entry_batchIP_B = self.add_input(frame, "C类网段", row=0, col=1, inivar="192.168.1.", entry_width=15)
|
||||||
|
self.entry_batchIP_B_begin = self.add_input(frame, "起始地址", row=0, col=2, inivar="1", entry_width=5)
|
||||||
|
self.entry_batchIP_B_end = self.add_input(frame, "结束地址", row=0, col=3, inivar="255", entry_width=5)
|
||||||
|
self.batchIP_startPing = self.add_button(frame, "开始", row=0, col=4, command=self.btn_batchIP_startPing)
|
||||||
|
self.batchIP_stopPing = self.add_button(frame, "停止", row=0, col=5, command=self.btn_batchIP_stopPing)
|
||||||
|
|
||||||
def create_outputping_section(self):
|
def create_outputping_section(self):
|
||||||
# 区域标签
|
# 区域标签
|
||||||
@@ -46,25 +49,9 @@ class PingTab(ttk.Frame, BasicUI):
|
|||||||
self.result_box = scrolledtext.ScrolledText(frame, width=100, height=20)
|
self.result_box = scrolledtext.ScrolledText(frame, width=100, height=20)
|
||||||
self.result_box.pack(pady=10)
|
self.result_box.pack(pady=10)
|
||||||
# --------------------------------------按钮回调函数--------------------------------------
|
# --------------------------------------按钮回调函数--------------------------------------
|
||||||
def btn_allIP_startPing(self):
|
|
||||||
if not self.entry_allIP['var'].get():
|
|
||||||
messagebox.showwarning("输入错误", "请输入IP或域名!")
|
|
||||||
return
|
|
||||||
logger.info(f"开始Ping {self.entry_allIP['var'].get()}")
|
|
||||||
self.ping_fun.strat_ping(self.entry_allIP['var'].get(), callback=self.allIP_ping_callback)
|
|
||||||
self.allIP_startPing['btn'].config(state='disabled')
|
|
||||||
|
|
||||||
def btn_allIP_stopPing(self):
|
|
||||||
logger.info(f"停止Ping {self.entry_allIP['var'].get()}")
|
|
||||||
self.ping_fun.stop_ping()
|
|
||||||
self.allIP_startPing['btn'].config(state='normal')
|
|
||||||
|
|
||||||
def allIP_ping_callback(self):
|
|
||||||
self.allIP_startPing['btn'].config(state='normal')
|
|
||||||
|
|
||||||
def btn_assignIP_startPing(self):
|
def btn_assignIP_startPing(self):
|
||||||
if not self.entry_assignIP_B['var'].get():
|
if not self.entry_assignIP_B['var'].get():
|
||||||
messagebox.showwarning("输入错误", "请输入IP或域名!")
|
messagebox.showwarning("输入错误", "请输入目标IP或域名!")
|
||||||
return
|
return
|
||||||
logger.info(f"开始由{self.entry_assignIP_A['var'].get()} Ping {self.entry_assignIP_B['var'].get()}")
|
logger.info(f"开始由{self.entry_assignIP_A['var'].get()} Ping {self.entry_assignIP_B['var'].get()}")
|
||||||
self.ping_fun.strat_ping(self.entry_assignIP_B['var'].get(),local_ip=self.entry_assignIP_A['var'].get(),
|
self.ping_fun.strat_ping(self.entry_assignIP_B['var'].get(),local_ip=self.entry_assignIP_A['var'].get(),
|
||||||
@@ -79,6 +66,53 @@ class PingTab(ttk.Frame, BasicUI):
|
|||||||
def assignIP_ping_callback(self):
|
def assignIP_ping_callback(self):
|
||||||
self.assignIP_startPing['btn'].config(state='normal')
|
self.assignIP_startPing['btn'].config(state='normal')
|
||||||
|
|
||||||
|
def btn_batchIP_startPing(self):
|
||||||
|
net_prefix = self.entry_batchIP_B['var'].get()
|
||||||
|
start = self.entry_batchIP_B_begin['var'].get()
|
||||||
|
end = self.entry_batchIP_B_end['var'].get()
|
||||||
|
local_ip = self.entry_batchIP_A['var'].get()
|
||||||
|
# ========= 输入参数检查 =========
|
||||||
|
if not net_prefix or start is None or end is None:
|
||||||
|
messagebox.showwarning("输入错误", "请输入完整的网段、起始地址和结束地址!")
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
start = int(start)
|
||||||
|
end = int(end)
|
||||||
|
except ValueError:
|
||||||
|
messagebox.showwarning("输入错误", "起始地址和结束地址必须是整数!")
|
||||||
|
return
|
||||||
|
if start < 1 or end > 255:
|
||||||
|
messagebox.showwarning("输入错误", "起始地址最小为1,结束地址最大为255!")
|
||||||
|
return
|
||||||
|
if start > end:
|
||||||
|
messagebox.showwarning("输入错误", "起始地址不能大于结束地址!")
|
||||||
|
return
|
||||||
|
if not net_prefix.endswith('.'):
|
||||||
|
messagebox.showwarning("输入错误", "网段必须以 '.' 结尾,例如:192.168.1.")
|
||||||
|
return
|
||||||
|
if local_ip == "":
|
||||||
|
logger.info(f"开始批量 Ping {net_prefix}{start} - {net_prefix}{end}")
|
||||||
|
else:
|
||||||
|
logger.info(f"开始由{local_ip} 批量 Ping {net_prefix}{start} - {net_prefix}{end}")
|
||||||
|
|
||||||
|
self.ping_fun.start_batch_ping(net_prefix, start, end, local_ip=local_ip, callback=self.batchIP_ping_callback)
|
||||||
|
self.batchIP_startPing['btn'].config(state='disabled')
|
||||||
|
|
||||||
|
def btn_batchIP_stopPing(self):
|
||||||
|
net_prefix = self.entry_batchIP_B['var'].get()
|
||||||
|
start = self.entry_batchIP_B_begin['var'].get()
|
||||||
|
end = self.entry_batchIP_B_end['var'].get()
|
||||||
|
local_ip = self.entry_batchIP_A['var'].get()
|
||||||
|
if local_ip == "":
|
||||||
|
logger.info(f"停止批量 Ping {net_prefix}{start} - {net_prefix}{end}")
|
||||||
|
else:
|
||||||
|
logger.info(f"停止由{local_ip} 批量 Ping {net_prefix}{start} - {net_prefix}{end}")
|
||||||
|
self.ping_fun.stop_batch_ping()
|
||||||
|
self.batchIP_startPing['btn'].config(state='normal')
|
||||||
|
|
||||||
|
def batchIP_ping_callback(self):
|
||||||
|
self.batchIP_startPing['btn'].config(state='normal')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user